diff options
120 files changed, 2088 insertions, 1246 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 48c99715..7e3eb600 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,7 +47,7 @@ if (GTAD_PATH) get_filename_component(ABS_GTAD_PATH "${GTAD_PATH}" ABSOLUTE) endif () if (MATRIX_DOC_PATH) - get_filename_component(ABS_API_DEF_PATH "${MATRIX_DOC_PATH}/api/client-server" ABSOLUTE) + get_filename_component(ABS_API_DEF_PATH "${MATRIX_DOC_PATH}/api" ABSOLUTE) endif () message( STATUS ) @@ -62,7 +62,7 @@ message( STATUS "Using Qt ${Qt5_VERSION} at ${Qt5_Prefix}" ) if (MATRIX_DOC_PATH AND GTAD_PATH) message( STATUS "Generating API stubs enabled" ) message( STATUS " Using GTAD at ${ABS_GTAD_PATH}" ) - message( STATUS " Using CS API files at ${ABS_API_DEF_PATH}" ) + message( STATUS " Using API files at ${ABS_API_DEF_PATH}" ) endif () message( STATUS "=============================================================================" ) message( STATUS ) @@ -102,21 +102,22 @@ set(libqmatrixclient_SRCS ) set(CSAPI_DIR csapi) -set(ASAPI_DIR application-service) set(FULL_CSAPI_DIR lib/${CSAPI_DIR}) -set(FULL_ASAPI_DIR lib/${ASAPI_DIR}) +set(FULL_CSAPI_SRC_DIR ${ABS_API_DEF_PATH}/client-server) +set(ASAPI_DEF_DIR application-service/definitions) +set(ISAPI_DEF_DIR identity/definitions) if (MATRIX_DOC_PATH AND GTAD_PATH) file(GLOB_RECURSE API_DEFS RELATIVE ${PROJECT_SOURCE_DIR} - ${ABS_API_DEF_PATH}/*.yaml - ${ABS_API_DEF_PATH}/definitions/*.yaml - ${MATRIX_DOC_PATH}/event-schemas/schema/* + ${FULL_CSAPI_SRC_DIR}/*.yaml + ${ABS_API_DEF_PATH}/${ASAPI_DEF_DIR}/*.yaml + ${ABS_API_DEF_PATH}/${ISAPI_DEF_DIR}/*.yaml ) add_custom_target(update-api ${ABS_GTAD_PATH} --config ${CSAPI_DIR}/gtad.yaml --out ${CSAPI_DIR} - ${ABS_API_DEF_PATH} + ${FULL_CSAPI_SRC_DIR} cas_login_redirect.yaml- cas_login_ticket.yaml- old_sync.yaml- room_initial_sync.yaml- # deprecated - sync.yaml- + sync.yaml- # we have a better handcrafted implementation WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/lib SOURCES ${FULL_CSAPI_DIR}/gtad.yaml ${FULL_CSAPI_DIR}/{{base}}.h.mustache @@ -128,13 +129,16 @@ endif() aux_source_directory(${FULL_CSAPI_DIR} libqmatrixclient_job_SRCS) aux_source_directory(${FULL_CSAPI_DIR}/definitions libqmatrixclient_csdef_SRCS) -aux_source_directory(${FULL_ASAPI_DIR}/definitions libqmatrixclient_asdef_SRCS) +aux_source_directory(${FULL_CSAPI_DIR}/definitions/wellknown libqmatrixclient_cswellknown_SRCS) +aux_source_directory(lib/${ASAPI_DEF_DIR} libqmatrixclient_asdef_SRCS) +aux_source_directory(lib/${ISAPI_DEF_DIR} libqmatrixclient_isdef_SRCS) set(example_SRCS examples/qmc-example.cpp) add_library(QMatrixClient ${libqmatrixclient_SRCS} ${libqmatrixclient_job_SRCS} ${libqmatrixclient_csdef_SRCS} - ${libqmatrixclient_asdef_SRCS}) + ${libqmatrixclient_cswellknown_SRCS} + ${libqmatrixclient_asdef_SRCS} ${libqmatrixclient_isdef_SRCS}) set(API_VERSION "0.4") set_property(TARGET QMatrixClient PROPERTY VERSION "${API_VERSION}.0") set_property(TARGET QMatrixClient PROPERTY SOVERSION 0 ) diff --git a/lib/application-service/definitions/location.cpp b/lib/application-service/definitions/location.cpp index 973bcd22..958a55bf 100644 --- a/lib/application-service/definitions/location.cpp +++ b/lib/application-service/definitions/location.cpp @@ -8,24 +8,23 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const ThirdPartyLocation& pod) { - QJsonObject _json; - addParam<IfNotEmpty>(_json, QStringLiteral("alias"), pod.alias); - addParam<IfNotEmpty>(_json, QStringLiteral("protocol"), pod.protocol); - addParam<IfNotEmpty>(_json, QStringLiteral("fields"), pod.fields); - return _json; + QJsonObject jo; + addParam<>(jo, QStringLiteral("alias"), pod.alias); + addParam<>(jo, QStringLiteral("protocol"), pod.protocol); + addParam<>(jo, QStringLiteral("fields"), pod.fields); + return jo; } -ThirdPartyLocation FromJson<ThirdPartyLocation>::operator()(const QJsonValue& jv) +ThirdPartyLocation FromJsonObject<ThirdPartyLocation>::operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); ThirdPartyLocation result; result.alias = - fromJson<QString>(_json.value("alias"_ls)); + fromJson<QString>(jo.value("alias"_ls)); result.protocol = - fromJson<QString>(_json.value("protocol"_ls)); + fromJson<QString>(jo.value("protocol"_ls)); result.fields = - fromJson<QJsonObject>(_json.value("fields"_ls)); - + fromJson<QJsonObject>(jo.value("fields"_ls)); + return result; } diff --git a/lib/application-service/definitions/location.h b/lib/application-service/definitions/location.h index 47d621e0..89b48a43 100644 --- a/lib/application-service/definitions/location.h +++ b/lib/application-service/definitions/location.h @@ -24,9 +24,9 @@ namespace QMatrixClient QJsonObject toJson(const ThirdPartyLocation& pod); - template <> struct FromJson<ThirdPartyLocation> + template <> struct FromJsonObject<ThirdPartyLocation> { - ThirdPartyLocation operator()(const QJsonValue& jv); + ThirdPartyLocation operator()(const QJsonObject& jo) const; }; } // namespace QMatrixClient diff --git a/lib/application-service/definitions/protocol.cpp b/lib/application-service/definitions/protocol.cpp index 5e70ff16..04bb7dfc 100644 --- a/lib/application-service/definitions/protocol.cpp +++ b/lib/application-service/definitions/protocol.cpp @@ -8,67 +8,73 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const FieldType& pod) { - QJsonObject _json; - addParam<IfNotEmpty>(_json, QStringLiteral("regexp"), pod.regexp); - addParam<IfNotEmpty>(_json, QStringLiteral("placeholder"), pod.placeholder); - return _json; + QJsonObject jo; + addParam<>(jo, QStringLiteral("regexp"), pod.regexp); + addParam<>(jo, QStringLiteral("placeholder"), pod.placeholder); + return jo; } -FieldType FromJson<FieldType>::operator()(const QJsonValue& jv) +FieldType FromJsonObject<FieldType>::operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); FieldType result; result.regexp = - fromJson<QString>(_json.value("regexp"_ls)); + fromJson<QString>(jo.value("regexp"_ls)); result.placeholder = - fromJson<QString>(_json.value("placeholder"_ls)); - + fromJson<QString>(jo.value("placeholder"_ls)); + return result; } -QJsonObject QMatrixClient::toJson(const FieldTypes& pod) +QJsonObject QMatrixClient::toJson(const ProtocolInstance& pod) { - QJsonObject _json; - addParam<IfNotEmpty>(_json, QStringLiteral("fieldname"), pod.fieldname); - return _json; + QJsonObject jo; + addParam<>(jo, QStringLiteral("desc"), pod.desc); + addParam<IfNotEmpty>(jo, QStringLiteral("icon"), pod.icon); + addParam<>(jo, QStringLiteral("fields"), pod.fields); + addParam<>(jo, QStringLiteral("network_id"), pod.networkId); + return jo; } -FieldTypes FromJson<FieldTypes>::operator()(const QJsonValue& jv) +ProtocolInstance FromJsonObject<ProtocolInstance>::operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); - FieldTypes result; - result.fieldname = - fromJson<FieldType>(_json.value("fieldname"_ls)); - + ProtocolInstance result; + result.desc = + fromJson<QString>(jo.value("desc"_ls)); + result.icon = + fromJson<QString>(jo.value("icon"_ls)); + result.fields = + fromJson<QJsonObject>(jo.value("fields"_ls)); + result.networkId = + fromJson<QString>(jo.value("network_id"_ls)); + return result; } QJsonObject QMatrixClient::toJson(const ThirdPartyProtocol& pod) { - QJsonObject _json; - addParam<IfNotEmpty>(_json, QStringLiteral("user_fields"), pod.userFields); - addParam<IfNotEmpty>(_json, QStringLiteral("location_fields"), pod.locationFields); - addParam<IfNotEmpty>(_json, QStringLiteral("icon"), pod.icon); - addParam<IfNotEmpty>(_json, QStringLiteral("field_types"), pod.fieldTypes); - addParam<IfNotEmpty>(_json, QStringLiteral("instances"), pod.instances); - return _json; + QJsonObject jo; + addParam<>(jo, QStringLiteral("user_fields"), pod.userFields); + addParam<>(jo, QStringLiteral("location_fields"), pod.locationFields); + addParam<>(jo, QStringLiteral("icon"), pod.icon); + addParam<>(jo, QStringLiteral("field_types"), pod.fieldTypes); + addParam<>(jo, QStringLiteral("instances"), pod.instances); + return jo; } -ThirdPartyProtocol FromJson<ThirdPartyProtocol>::operator()(const QJsonValue& jv) +ThirdPartyProtocol FromJsonObject<ThirdPartyProtocol>::operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); ThirdPartyProtocol result; result.userFields = - fromJson<QStringList>(_json.value("user_fields"_ls)); + fromJson<QStringList>(jo.value("user_fields"_ls)); result.locationFields = - fromJson<QStringList>(_json.value("location_fields"_ls)); + fromJson<QStringList>(jo.value("location_fields"_ls)); result.icon = - fromJson<QString>(_json.value("icon"_ls)); + fromJson<QString>(jo.value("icon"_ls)); result.fieldTypes = - fromJson<FieldTypes>(_json.value("field_types"_ls)); + fromJson<QHash<QString, FieldType>>(jo.value("field_types"_ls)); result.instances = - fromJson<QVector<QJsonObject>>(_json.value("instances"_ls)); - + fromJson<QVector<ProtocolInstance>>(jo.value("instances"_ls)); + return result; } diff --git a/lib/application-service/definitions/protocol.h b/lib/application-service/definitions/protocol.h index a25688e7..2aca7d66 100644 --- a/lib/application-service/definitions/protocol.h +++ b/lib/application-service/definitions/protocol.h @@ -6,9 +6,10 @@ #include "converters.h" +#include <QtCore/QHash> #include <QtCore/QJsonObject> -#include <QtCore/QVector> #include "converters.h" +#include <QtCore/QVector> namespace QMatrixClient { @@ -17,7 +18,9 @@ namespace QMatrixClient /// Definition of valid values for a field. struct FieldType { - /// A regular expression for validation of a field's value. + /// A regular expression for validation of a field's value. This may be relatively + /// coarse to verify the value as the application service providing this protocol + /// may apply additional validation or filtering. QString regexp; /// An placeholder serving as a valid example of the field value. QString placeholder; @@ -25,46 +28,62 @@ namespace QMatrixClient QJsonObject toJson(const FieldType& pod); - template <> struct FromJson<FieldType> + template <> struct FromJsonObject<FieldType> { - FieldType operator()(const QJsonValue& jv); + FieldType operator()(const QJsonObject& jo) const; }; - /// All location or user fields should have an entry here. - struct FieldTypes + struct ProtocolInstance { - /// Definition of valid values for a field. - Omittable<FieldType> fieldname; + /// A human-readable description for the protocol, such as the name. + QString desc; + /// An optional content URI representing the protocol. Overrides the one provided + /// at the higher level Protocol object. + QString icon; + /// Preset values for ``fields`` the client may use to search by. + QJsonObject fields; + /// A unique identifier across all instances. + QString networkId; }; - QJsonObject toJson(const FieldTypes& pod); + QJsonObject toJson(const ProtocolInstance& pod); - template <> struct FromJson<FieldTypes> + template <> struct FromJsonObject<ProtocolInstance> { - FieldTypes operator()(const QJsonValue& jv); + ProtocolInstance operator()(const QJsonObject& jo) const; }; struct ThirdPartyProtocol { - /// Fields used to identify a third party user. + /// Fields which may be used to identify a third party user. These should be + /// ordered to suggest the way that entities may be grouped, where higher + /// groupings are ordered first. For example, the name of a network should be + /// searched before the nickname of a user. QStringList userFields; - /// Fields used to identify a third party location. + /// Fields which may be used to identify a third party location. These should be + /// ordered to suggest the way that entities may be grouped, where higher + /// groupings are ordered first. For example, the name of a network should be + /// searched before the name of a channel. QStringList locationFields; - /// An icon representing the third party protocol. + /// A content URI representing an icon for the third party protocol. QString icon; - /// All location or user fields should have an entry here. - Omittable<FieldTypes> fieldTypes; + /// The type definitions for the fields defined in the ``user_fields`` and + /// ``location_fields``. Each entry in those arrays MUST have an entry here. The + /// ``string`` key for this object is field name itself. + /// + /// May be an empty object if no fields are defined. + QHash<QString, FieldType> fieldTypes; /// A list of objects representing independent instances of configuration. - /// For instance multiple networks on IRC if multiple are bridged by the - /// same bridge. - QVector<QJsonObject> instances; + /// For example, multiple networks on IRC if multiple are provided by the + /// same application service. + QVector<ProtocolInstance> instances; }; QJsonObject toJson(const ThirdPartyProtocol& pod); - template <> struct FromJson<ThirdPartyProtocol> + template <> struct FromJsonObject<ThirdPartyProtocol> { - ThirdPartyProtocol operator()(const QJsonValue& jv); + ThirdPartyProtocol operator()(const QJsonObject& jo) const; }; } // namespace QMatrixClient diff --git a/lib/application-service/definitions/user.cpp b/lib/application-service/definitions/user.cpp index 17687cfd..ca334236 100644 --- a/lib/application-service/definitions/user.cpp +++ b/lib/application-service/definitions/user.cpp @@ -8,24 +8,23 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const ThirdPartyUser& pod) { - QJsonObject _json; - addParam<IfNotEmpty>(_json, QStringLiteral("userid"), pod.userid); - addParam<IfNotEmpty>(_json, QStringLiteral("protocol"), pod.protocol); - addParam<IfNotEmpty>(_json, QStringLiteral("fields"), pod.fields); - return _json; + QJsonObject jo; + addParam<>(jo, QStringLiteral("userid"), pod.userid); + addParam<>(jo, QStringLiteral("protocol"), pod.protocol); + addParam<>(jo, QStringLiteral("fields"), pod.fields); + return jo; } -ThirdPartyUser FromJson<ThirdPartyUser>::operator()(const QJsonValue& jv) +ThirdPartyUser FromJsonObject<ThirdPartyUser>::operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); ThirdPartyUser result; result.userid = - fromJson<QString>(_json.value("userid"_ls)); + fromJson<QString>(jo.value("userid"_ls)); result.protocol = - fromJson<QString>(_json.value("protocol"_ls)); + fromJson<QString>(jo.value("protocol"_ls)); result.fields = - fromJson<QJsonObject>(_json.value("fields"_ls)); - + fromJson<QJsonObject>(jo.value("fields"_ls)); + return result; } diff --git a/lib/application-service/definitions/user.h b/lib/application-service/definitions/user.h index 9c64a7ba..79ca7789 100644 --- a/lib/application-service/definitions/user.h +++ b/lib/application-service/definitions/user.h @@ -24,9 +24,9 @@ namespace QMatrixClient QJsonObject toJson(const ThirdPartyUser& pod); - template <> struct FromJson<ThirdPartyUser> + template <> struct FromJsonObject<ThirdPartyUser> { - ThirdPartyUser operator()(const QJsonValue& jv); + ThirdPartyUser operator()(const QJsonObject& jo) const; }; } // namespace QMatrixClient diff --git a/lib/converters.h b/lib/converters.h index 7f78effe..70938ab9 100644 --- a/lib/converters.h +++ b/lib/converters.h @@ -22,6 +22,7 @@ #include <QtCore/QJsonObject> #include <QtCore/QJsonArray> // Includes <QtCore/QJsonValue> +#include <QtCore/QJsonDocument> #include <QtCore/QDate> #include <QtCore/QUrlQuery> #include <QtCore/QSet> @@ -80,7 +81,7 @@ namespace QMatrixClient // non-explicit constructors. QJsonValue variantToJson(const QVariant& v); template <typename T> - inline auto toJson(T&& var) + inline auto toJson(T&& /* const QVariant& or QVariant&& */ var) -> std::enable_if_t<std::is_same<std::decay_t<T>, QVariant>::value, QJsonValue> { @@ -137,17 +138,36 @@ namespace QMatrixClient } template <typename T> + struct FromJsonObject + { + T operator()(const QJsonObject& jo) const { return T(jo); } + }; + + template <typename T> struct FromJson { - T operator()(const QJsonValue& jv) const { return T(jv); } + T operator()(const QJsonValue& jv) const + { + return FromJsonObject<T>()(jv.toObject()); + } + T operator()(const QJsonDocument& jd) const + { + return FromJsonObject<T>()(jd.object()); + } }; template <typename T> - inline T fromJson(const QJsonValue& jv) + inline auto fromJson(const QJsonValue& jv) { return FromJson<T>()(jv); } + template <typename T> + inline auto fromJson(const QJsonDocument& jd) + { + return FromJson<T>()(jd); + } + template <> struct FromJson<bool> { auto operator()(const QJsonValue& jv) const { return jv.toBool(); } @@ -194,14 +214,6 @@ namespace QMatrixClient } }; - template <> struct FromJson<QJsonObject> - { - auto operator()(const QJsonValue& jv) const - { - return jv.toObject(); - } - }; - template <> struct FromJson<QJsonArray> { auto operator()(const QJsonValue& jv) const @@ -223,31 +235,35 @@ namespace QMatrixClient QVariant operator()(const QJsonValue& jv) const; }; - template <typename T> struct FromJson<std::vector<T>> + template <typename VectorT> + struct ArrayFromJson { - auto operator()(const QJsonValue& jv) const + auto operator()(const QJsonArray& ja) const { - using size_type = typename std::vector<T>::size_type; - const auto jsonArray = jv.toArray(); - std::vector<T> vect; vect.resize(size_type(jsonArray.size())); - std::transform(jsonArray.begin(), jsonArray.end(), - vect.begin(), FromJson<T>()); + using size_type = typename VectorT::size_type; + VectorT vect; vect.resize(size_type(ja.size())); + std::transform(ja.begin(), ja.end(), + vect.begin(), FromJson<typename VectorT::value_type>()); return vect; } - }; - - template <typename T> struct FromJson<QVector<T>> - { auto operator()(const QJsonValue& jv) const { - const auto jsonArray = jv.toArray(); - QVector<T> vect; vect.resize(jsonArray.size()); - std::transform(jsonArray.begin(), jsonArray.end(), - vect.begin(), FromJson<T>()); - return vect; + return operator()(jv.toArray()); + } + auto operator()(const QJsonDocument& jd) const + { + return operator()(jd.array()); } }; + template <typename T> + struct FromJson<std::vector<T>> : ArrayFromJson<std::vector<T>> + { }; + + template <typename T> + struct FromJson<QVector<T>> : ArrayFromJson<QVector<T>> + { }; + template <typename T> struct FromJson<QList<T>> { auto operator()(const QJsonValue& jv) const @@ -279,18 +295,36 @@ namespace QMatrixClient } }; - template <typename T> struct FromJson<QHash<QString, T>> + template <typename HashMapT> + struct HashMapFromJson { - auto operator()(const QJsonValue& jv) const + auto operator()(const QJsonObject& jo) const { - const auto json = jv.toObject(); - QHash<QString, T> h; h.reserve(json.size()); - for (auto it = json.begin(); it != json.end(); ++it) - h.insert(it.key(), fromJson<T>(it.value())); + HashMapT h; h.reserve(jo.size()); + for (auto it = jo.begin(); it != jo.end(); ++it) + h[it.key()] = + fromJson<typename HashMapT::mapped_type>(it.value()); return h; } + auto operator()(const QJsonValue& jv) const + { + return operator()(jv.toObject()); + } + auto operator()(const QJsonDocument& jd) const + { + return operator()(jd.object()); + } }; + template <typename T> + struct FromJson<std::unordered_map<QString, T>> + : HashMapFromJson<std::unordered_map<QString, T>> + { }; + + template <typename T> + struct FromJson<QHash<QString, T>> : HashMapFromJson<QHash<QString, T>> + { }; + #if (QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)) template <> struct FromJson<QHash<QString, QVariant>> { @@ -298,18 +332,6 @@ namespace QMatrixClient }; #endif - template <typename T> struct FromJson<std::unordered_map<QString, T>> - { - auto operator()(const QJsonValue& jv) const - { - const auto json = jv.toObject(); - std::unordered_map<QString, T> h; h.reserve(size_t(json.size())); - for (auto it = json.begin(); it != json.end(); ++it) - h.insert(std::make_pair(it.key(), fromJson<T>(it.value()))); - return h; - } - }; - // Conditional insertion into a QJsonObject namespace _impl diff --git a/lib/csapi/account-data.h b/lib/csapi/account-data.h index d8ae0aa1..f3656a14 100644 --- a/lib/csapi/account-data.h +++ b/lib/csapi/account-data.h @@ -13,7 +13,7 @@ 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``. @@ -21,20 +21,20 @@ namespace QMatrixClient { public: /*! Set some account_data for the user. - * \param userId + * \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 + * \param type * The event type of the account_data to set. Custom types should be * namespaced to avoid clashes. - * \param content + * \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``. @@ -42,15 +42,15 @@ namespace QMatrixClient { public: /*! Set some account_data for the user. - * \param userId + * \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 + * \param roomId * The id of the room to set account_data on. - * \param type + * \param type * The event type of the account_data to set. Custom types should be * namespaced to avoid clashes. - * \param content + * \param content * The content of the account_data */ explicit SetAccountDataPerRoomJob(const QString& userId, const QString& roomId, const QString& type, const QJsonObject& content = {}); diff --git a/lib/csapi/admin.cpp b/lib/csapi/admin.cpp index 3effbbc3..6066d4d9 100644 --- a/lib/csapi/admin.cpp +++ b/lib/csapi/admin.cpp @@ -16,44 +16,41 @@ namespace QMatrixClient { // Converters - template <> struct FromJson<GetWhoIsJob::ConnectionInfo> + template <> struct FromJsonObject<GetWhoIsJob::ConnectionInfo> { - GetWhoIsJob::ConnectionInfo operator()(const QJsonValue& jv) + GetWhoIsJob::ConnectionInfo operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); GetWhoIsJob::ConnectionInfo result; result.ip = - fromJson<QString>(_json.value("ip"_ls)); + fromJson<QString>(jo.value("ip"_ls)); result.lastSeen = - fromJson<qint64>(_json.value("last_seen"_ls)); + fromJson<qint64>(jo.value("last_seen"_ls)); result.userAgent = - fromJson<QString>(_json.value("user_agent"_ls)); + fromJson<QString>(jo.value("user_agent"_ls)); return result; } }; - template <> struct FromJson<GetWhoIsJob::SessionInfo> + template <> struct FromJsonObject<GetWhoIsJob::SessionInfo> { - GetWhoIsJob::SessionInfo operator()(const QJsonValue& jv) + GetWhoIsJob::SessionInfo operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); GetWhoIsJob::SessionInfo result; result.connections = - fromJson<QVector<GetWhoIsJob::ConnectionInfo>>(_json.value("connections"_ls)); + fromJson<QVector<GetWhoIsJob::ConnectionInfo>>(jo.value("connections"_ls)); return result; } }; - template <> struct FromJson<GetWhoIsJob::DeviceInfo> + template <> struct FromJsonObject<GetWhoIsJob::DeviceInfo> { - GetWhoIsJob::DeviceInfo operator()(const QJsonValue& jv) + GetWhoIsJob::DeviceInfo operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); GetWhoIsJob::DeviceInfo result; result.sessions = - fromJson<QVector<GetWhoIsJob::SessionInfo>>(_json.value("sessions"_ls)); + fromJson<QVector<GetWhoIsJob::SessionInfo>>(jo.value("sessions"_ls)); return result; } diff --git a/lib/csapi/admin.h b/lib/csapi/admin.h index a0c43fb9..d35f3ee3 100644 --- a/lib/csapi/admin.h +++ b/lib/csapi/admin.h @@ -15,7 +15,7 @@ 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 @@ -66,7 +66,7 @@ namespace QMatrixClient // Construction/destruction /*! Gets information about a particular user. - * \param userId + * \param userId * The user to look up. */ explicit GetWhoIsJob(const QString& userId); diff --git a/lib/csapi/administrative_contact.cpp b/lib/csapi/administrative_contact.cpp index bcbba5b5..f62002a6 100644 --- a/lib/csapi/administrative_contact.cpp +++ b/lib/csapi/administrative_contact.cpp @@ -16,16 +16,19 @@ namespace QMatrixClient { // Converters - template <> struct FromJson<GetAccount3PIDsJob::ThirdPartyIdentifier> + template <> struct FromJsonObject<GetAccount3PIDsJob::ThirdPartyIdentifier> { - GetAccount3PIDsJob::ThirdPartyIdentifier operator()(const QJsonValue& jv) + GetAccount3PIDsJob::ThirdPartyIdentifier operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); GetAccount3PIDsJob::ThirdPartyIdentifier result; result.medium = - fromJson<QString>(_json.value("medium"_ls)); + fromJson<QString>(jo.value("medium"_ls)); result.address = - fromJson<QString>(_json.value("address"_ls)); + fromJson<QString>(jo.value("address"_ls)); + result.validatedAt = + fromJson<qint64>(jo.value("validated_at"_ls)); + result.addedAt = + fromJson<qint64>(jo.value("added_at"_ls)); return result; } @@ -73,11 +76,11 @@ namespace QMatrixClient QJsonObject toJson(const Post3PIDsJob::ThreePidCredentials& pod) { - QJsonObject _json; - addParam<>(_json, QStringLiteral("client_secret"), pod.clientSecret); - addParam<>(_json, QStringLiteral("id_server"), pod.idServer); - addParam<>(_json, QStringLiteral("sid"), pod.sid); - return _json; + QJsonObject jo; + addParam<>(jo, QStringLiteral("client_secret"), pod.clientSecret); + addParam<>(jo, QStringLiteral("id_server"), pod.idServer); + addParam<>(jo, QStringLiteral("sid"), pod.sid); + return jo; } } // namespace QMatrixClient @@ -93,31 +96,86 @@ Post3PIDsJob::Post3PIDsJob(const ThreePidCredentials& threePidCreds, bool bind) setRequestData(_data); } -QUrl RequestTokenTo3PIDEmailJob::makeRequestUrl(QUrl baseUrl) +static const auto Delete3pidFromAccountJobName = QStringLiteral("Delete3pidFromAccountJob"); + +Delete3pidFromAccountJob::Delete3pidFromAccountJob(const QString& medium, const QString& address) + : BaseJob(HttpVerb::Post, Delete3pidFromAccountJobName, + basePath % "/account/3pid/delete") { - return BaseJob::makeRequestUrl(std::move(baseUrl), - basePath % "/account/3pid/email/requestToken"); + QJsonObject _data; + addParam<>(_data, QStringLiteral("medium"), medium); + addParam<>(_data, QStringLiteral("address"), address); + setRequestData(_data); } +class RequestTokenTo3PIDEmailJob::Private +{ + public: + Sid data; +}; + static const auto RequestTokenTo3PIDEmailJobName = QStringLiteral("RequestTokenTo3PIDEmailJob"); -RequestTokenTo3PIDEmailJob::RequestTokenTo3PIDEmailJob() +RequestTokenTo3PIDEmailJob::RequestTokenTo3PIDEmailJob(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) +{ + QJsonObject _data; + addParam<>(_data, QStringLiteral("client_secret"), clientSecret); + addParam<>(_data, QStringLiteral("email"), email); + addParam<>(_data, QStringLiteral("send_attempt"), sendAttempt); + addParam<IfNotEmpty>(_data, QStringLiteral("next_link"), nextLink); + addParam<>(_data, QStringLiteral("id_server"), idServer); + setRequestData(_data); +} + +RequestTokenTo3PIDEmailJob::~RequestTokenTo3PIDEmailJob() = default; + +const Sid& RequestTokenTo3PIDEmailJob::data() const { + return d->data; } -QUrl RequestTokenTo3PIDMSISDNJob::makeRequestUrl(QUrl baseUrl) +BaseJob::Status RequestTokenTo3PIDEmailJob::parseJson(const QJsonDocument& data) { - return BaseJob::makeRequestUrl(std::move(baseUrl), - basePath % "/account/3pid/msisdn/requestToken"); + d->data = fromJson<Sid>(data); + return Success; } +class RequestTokenTo3PIDMSISDNJob::Private +{ + public: + Sid data; +}; + static const auto RequestTokenTo3PIDMSISDNJobName = QStringLiteral("RequestTokenTo3PIDMSISDNJob"); -RequestTokenTo3PIDMSISDNJob::RequestTokenTo3PIDMSISDNJob() +RequestTokenTo3PIDMSISDNJob::RequestTokenTo3PIDMSISDNJob(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) +{ + QJsonObject _data; + addParam<>(_data, QStringLiteral("client_secret"), clientSecret); + addParam<>(_data, QStringLiteral("country"), country); + addParam<>(_data, QStringLiteral("phone_number"), phoneNumber); + addParam<>(_data, QStringLiteral("send_attempt"), sendAttempt); + addParam<IfNotEmpty>(_data, QStringLiteral("next_link"), nextLink); + addParam<>(_data, QStringLiteral("id_server"), idServer); + setRequestData(_data); +} + +RequestTokenTo3PIDMSISDNJob::~RequestTokenTo3PIDMSISDNJob() = default; + +const Sid& RequestTokenTo3PIDMSISDNJob::data() const { + return d->data; +} + +BaseJob::Status RequestTokenTo3PIDMSISDNJob::parseJson(const QJsonDocument& data) +{ + d->data = fromJson<Sid>(data); + return Success; } diff --git a/lib/csapi/administrative_contact.h b/lib/csapi/administrative_contact.h index 112b81cc..3fb3d44c 100644 --- a/lib/csapi/administrative_contact.h +++ b/lib/csapi/administrative_contact.h @@ -6,6 +6,7 @@ #include "jobs/basejob.h" +#include "csapi/../identity/definitions/sid.h" #include "converters.h" #include <QtCore/QVector> @@ -14,12 +15,12 @@ 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. + /// 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. @@ -32,7 +33,7 @@ namespace QMatrixClient /// 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. + /// 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. @@ -42,6 +43,11 @@ namespace QMatrixClient 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 @@ -64,7 +70,7 @@ namespace QMatrixClient /// 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. + /// 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. @@ -79,7 +85,7 @@ namespace QMatrixClient }; /// Adds contact information to the user's account. - /// + /// /// Adds contact information to the user's account. class Post3PIDsJob : public BaseJob { @@ -89,20 +95,20 @@ namespace QMatrixClient /// The third party credentials to associate with the account. struct ThreePidCredentials { - /// The client secret used in the session with the Identity Server. + /// The client secret used in the session with the identity server. QString clientSecret; - /// The Identity Server to use. + /// The identity server to use. QString idServer; - /// The session identifier given by the Identity Server. + /// The session identifier given by the identity server. QString sid; }; // Construction/destruction /*! Adds contact information to the user's account. - * \param threePidCreds + * \param threePidCreds * The third party credentials to associate with the account. - * \param bind + * \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``. @@ -110,49 +116,122 @@ namespace QMatrixClient explicit Post3PIDsJob(const ThreePidCredentials& threePidCreds, bool bind = false); }; - /// Requests a validation token be sent to the given email address for the purpose of adding an email address to an account - /// - /// Proxies the identity server API ``validate/email/requestToken``, but + /// 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 Home Server. This API should be used to request + /// 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 is identical to that of the HS API - /// |/register/email/requestToken|_ endpoint. + /// parameters and response are identical to that of the |/register/email/requestToken|_ + /// endpoint. class RequestTokenTo3PIDEmailJob : public BaseJob { public: - explicit RequestTokenTo3PIDEmailJob(); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * RequestTokenTo3PIDEmailJob is necessary but the job - * itself isn't. + /*! 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. */ - static QUrl makeRequestUrl(QUrl baseUrl); + 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; }; - /// Requests a validation token be sent to the given email address for the purpose of adding a phone number to an account. - /// - /// Proxies the identity server API ``validate/msisdn/requestToken``, but + /// 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 Home Server. This API should be used to request + /// 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 is identical to that of the HS API - /// |/register/msisdn/requestToken|_ endpoint. + /// parameters and response are identical to that of the |/register/msisdn/requestToken|_ + /// endpoint. class RequestTokenTo3PIDMSISDNJob : public BaseJob { public: - explicit RequestTokenTo3PIDMSISDNJob(); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * RequestTokenTo3PIDMSISDNJob is necessary but the job - * itself isn't. + /*! 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. */ - static QUrl makeRequestUrl(QUrl baseUrl); + 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 new file mode 100644 index 00000000..f40e2f05 --- /dev/null +++ b/lib/csapi/appservice_room_directory.cpp @@ -0,0 +1,25 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + +#include "appservice_room_directory.h" + +#include "converters.h" + +#include <QtCore/QStringBuilder> + +using namespace QMatrixClient; + +static const auto basePath = QStringLiteral("/_matrix/client/r0"); + +static const auto UpdateAppserviceRoomDirectoryVsibilityJobName = QStringLiteral("UpdateAppserviceRoomDirectoryVsibilityJob"); + +UpdateAppserviceRoomDirectoryVsibilityJob::UpdateAppserviceRoomDirectoryVsibilityJob(const QString& networkId, const QString& roomId, const QString& visibility) + : BaseJob(HttpVerb::Put, UpdateAppserviceRoomDirectoryVsibilityJobName, + basePath % "/directory/list/appservice/" % networkId % "/" % roomId) +{ + QJsonObject _data; + addParam<>(_data, QStringLiteral("visibility"), visibility); + setRequestData(_data); +} + diff --git a/lib/csapi/appservice_room_directory.h b/lib/csapi/appservice_room_directory.h new file mode 100644 index 00000000..f35198b3 --- /dev/null +++ b/lib/csapi/appservice_room_directory.h @@ -0,0 +1,41 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + +#pragma once + +#include "jobs/basejob.h" + + +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); + }; +} // namespace QMatrixClient diff --git a/lib/csapi/banning.h b/lib/csapi/banning.h index 196ddf66..237bd2a0 100644 --- a/lib/csapi/banning.h +++ b/lib/csapi/banning.h @@ -12,7 +12,7 @@ namespace QMatrixClient // 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. @@ -22,18 +22,18 @@ namespace QMatrixClient { public: /*! Ban a user in the room. - * \param roomId + * \param roomId * The room identifier (not alias) from which the user should be banned. - * \param userId + * \param userId * The fully qualified user ID of the user being banned. - * \param reason + * \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. /// @@ -42,9 +42,9 @@ namespace QMatrixClient { public: /*! Unban a user from the room. - * \param roomId + * \param roomId * The room identifier (not alias) from which the user should be unbanned. - * \param userId + * \param userId * The fully qualified user ID of the user being unbanned. */ explicit UnbanJob(const QString& roomId, const QString& userId); diff --git a/lib/csapi/content-repo.cpp b/lib/csapi/content-repo.cpp index f686683c..9b590e42 100644 --- a/lib/csapi/content-repo.cpp +++ b/lib/csapi/content-repo.cpp @@ -109,8 +109,8 @@ QIODevice* GetContentJob::data() const BaseJob::Status GetContentJob::parseReply(QNetworkReply* reply) { - d->contentType = reply->rawHeader("Content-Type"); - d->contentDisposition = reply->rawHeader("Content-Disposition"); + d->contentType = reply->rawHeader("Content-Type"); + d->contentDisposition = reply->rawHeader("Content-Disposition"); d->data = reply; return Success; } @@ -168,8 +168,8 @@ QIODevice* GetContentOverrideNameJob::data() const BaseJob::Status GetContentOverrideNameJob::parseReply(QNetworkReply* reply) { - d->contentType = reply->rawHeader("Content-Type"); - d->contentDisposition = reply->rawHeader("Content-Disposition"); + d->contentType = reply->rawHeader("Content-Type"); + d->contentDisposition = reply->rawHeader("Content-Disposition"); d->data = reply; return Success; } @@ -224,7 +224,7 @@ QIODevice* GetContentThumbnailJob::data() const BaseJob::Status GetContentThumbnailJob::parseReply(QNetworkReply* reply) { - d->contentType = reply->rawHeader("Content-Type"); + d->contentType = reply->rawHeader("Content-Type"); d->data = reply; return Success; } @@ -284,7 +284,7 @@ BaseJob::Status GetUrlPreviewJob::parseJson(const QJsonDocument& data) class GetConfigJob::Private { public: - Omittable<double> uploadSize; + Omittable<qint64> uploadSize; }; QUrl GetConfigJob::makeRequestUrl(QUrl baseUrl) @@ -304,7 +304,7 @@ GetConfigJob::GetConfigJob() GetConfigJob::~GetConfigJob() = default; -Omittable<double> GetConfigJob::uploadSize() const +Omittable<qint64> GetConfigJob::uploadSize() const { return d->uploadSize; } @@ -312,7 +312,7 @@ Omittable<double> GetConfigJob::uploadSize() const BaseJob::Status GetConfigJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->uploadSize = fromJson<double>(json.value("m.upload.size"_ls)); + d->uploadSize = fromJson<qint64>(json.value("m.upload.size"_ls)); return Success; } diff --git a/lib/csapi/content-repo.h b/lib/csapi/content-repo.h index 85d7cb49..5ef2e0d6 100644 --- a/lib/csapi/content-repo.h +++ b/lib/csapi/content-repo.h @@ -18,10 +18,10 @@ namespace QMatrixClient { public: /*! Upload some content to the content repository. - * \param content - * \param filename + * \param content + * \param filename * The name of the file being uploaded - * \param contentType + * \param contentType * The content type of the file being uploaded */ explicit UploadContentJob(QIODevice* content, const QString& filename = {}, const QString& contentType = {}); @@ -45,11 +45,11 @@ namespace QMatrixClient { public: /*! Download content from the content repository. - * \param serverName + * \param serverName * The server name from the ``mxc://`` URI (the authoritory component) - * \param mediaId + * \param mediaId * The media ID from the ``mxc://`` URI (the path component) - * \param allowRemote + * \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. @@ -88,13 +88,13 @@ namespace QMatrixClient { public: /*! Download content from the content repository as a given filename. - * \param serverName + * \param serverName * The server name from the ``mxc://`` URI (the authoritory component) - * \param mediaId + * \param mediaId * The media ID from the ``mxc://`` URI (the path component) - * \param fileName + * \param fileName * The filename to give in the Content-Disposition - * \param allowRemote + * \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. @@ -133,19 +133,19 @@ namespace QMatrixClient { public: /*! Download a thumbnail of the content from the content repository. - * \param serverName + * \param serverName * The server name from the ``mxc://`` URI (the authoritory component) - * \param mediaId + * \param mediaId * The media ID from the ``mxc://`` URI (the path component) - * \param width + * \param width * The *desired* width of the thumbnail. The actual thumbnail may not * match the size specified. - * \param height + * \param height * The *desired* height of the thumbnail. The actual thumbnail may not * match the size specified. - * \param method + * \param method * The desired resizing method. - * \param allowRemote + * \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. @@ -182,9 +182,9 @@ namespace QMatrixClient { public: /*! Get information about a URL for a client - * \param url + * \param url * The URL to get a preview of - * \param ts + * \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. @@ -217,7 +217,7 @@ namespace QMatrixClient }; /// 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. @@ -248,7 +248,7 @@ namespace QMatrixClient /// 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<double> uploadSize() const; + Omittable<qint64> uploadSize() const; protected: Status parseJson(const QJsonDocument& data) override; diff --git a/lib/csapi/create_room.cpp b/lib/csapi/create_room.cpp index 068b567f..36f83727 100644 --- a/lib/csapi/create_room.cpp +++ b/lib/csapi/create_room.cpp @@ -18,20 +18,20 @@ namespace QMatrixClient QJsonObject toJson(const CreateRoomJob::Invite3pid& pod) { - QJsonObject _json; - addParam<>(_json, QStringLiteral("id_server"), pod.idServer); - addParam<>(_json, QStringLiteral("medium"), pod.medium); - addParam<>(_json, QStringLiteral("address"), pod.address); - return _json; + QJsonObject jo; + addParam<>(jo, QStringLiteral("id_server"), pod.idServer); + addParam<>(jo, QStringLiteral("medium"), pod.medium); + addParam<>(jo, QStringLiteral("address"), pod.address); + return jo; } QJsonObject toJson(const CreateRoomJob::StateEvent& pod) { - QJsonObject _json; - addParam<>(_json, QStringLiteral("type"), pod.type); - addParam<IfNotEmpty>(_json, QStringLiteral("state_key"), pod.stateKey); - addParam<>(_json, QStringLiteral("content"), pod.content); - return _json; + QJsonObject jo; + addParam<>(jo, QStringLiteral("type"), pod.type); + addParam<IfNotEmpty>(jo, QStringLiteral("state_key"), pod.stateKey); + addParam<>(jo, QStringLiteral("content"), pod.content); + return jo; } } // namespace QMatrixClient diff --git a/lib/csapi/create_room.h b/lib/csapi/create_room.h index 60579a83..a0a64df0 100644 --- a/lib/csapi/create_room.h +++ b/lib/csapi/create_room.h @@ -15,7 +15,7 @@ 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 @@ -43,13 +43,13 @@ namespace QMatrixClient /// ======================== ============== ====================== ================ ========= /// Preset ``join_rules`` ``history_visibility`` ``guest_access`` Other /// ======================== ============== ====================== ================ ========= - /// ``private_chat`` ``invite`` ``shared`` ``can_join`` + /// ``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`` + /// ``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 + /// requesting user as the creator, alongside other keys provided in the /// ``creation_content``. class CreateRoomJob : public BaseJob { @@ -83,13 +83,13 @@ namespace QMatrixClient /// ======================== ============== ====================== ================ ========= /// Preset ``join_rules`` ``history_visibility`` ``guest_access`` Other /// ======================== ============== ====================== ================ ========= - /// ``private_chat`` ``invite`` ``shared`` ``can_join`` + /// ``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`` + /// ``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 + /// requesting user as the creator, alongside other keys provided in the /// ``creation_content``. struct Invite3pid { @@ -128,13 +128,13 @@ namespace QMatrixClient /// ======================== ============== ====================== ================ ========= /// Preset ``join_rules`` ``history_visibility`` ``guest_access`` Other /// ======================== ============== ====================== ================ ========= - /// ``private_chat`` ``invite`` ``shared`` ``can_join`` + /// ``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`` + /// ``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 + /// requesting user as the creator, alongside other keys provided in the /// ``creation_content``. struct StateEvent { @@ -149,14 +149,14 @@ namespace QMatrixClient // Construction/destruction /*! Create a new room - * \param visibility + * \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 + * \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 @@ -166,31 +166,31 @@ namespace QMatrixClient * * The complete room alias will become the canonical alias for * the room. - * \param name + * \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 + * \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 + * \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 + * \param invite3pid * A list of objects representing third party IDs to invite into * the room. - * \param roomVersion + * \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 + * \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 + * \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 @@ -198,19 +198,19 @@ namespace QMatrixClient * * Takes precedence over events set by ``preset``, but gets * overriden by ``name`` and ``topic`` keys. - * \param preset + * \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 + * ``public_chat`` and ``private`` visibility equates to a preset of * ``private_chat``. - * \param isDirect + * \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 + * \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 diff --git a/lib/csapi/definitions/auth_data.cpp b/lib/csapi/definitions/auth_data.cpp index 94e3c05c..f8639432 100644 --- a/lib/csapi/definitions/auth_data.cpp +++ b/lib/csapi/definitions/auth_data.cpp @@ -8,22 +8,21 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const AuthenticationData& pod) { - QJsonObject _json = toJson(pod.authInfo); - addParam<>(_json, QStringLiteral("type"), pod.type); - addParam<IfNotEmpty>(_json, QStringLiteral("session"), pod.session); - return _json; + QJsonObject jo = toJson(pod.authInfo); + addParam<>(jo, QStringLiteral("type"), pod.type); + addParam<IfNotEmpty>(jo, QStringLiteral("session"), pod.session); + return jo; } -AuthenticationData FromJson<AuthenticationData>::operator()(const QJsonValue& jv) +AuthenticationData FromJsonObject<AuthenticationData>::operator()(QJsonObject jo) const { - auto _json = jv.toObject(); AuthenticationData result; result.type = - fromJson<QString>(_json.take("type"_ls)); + fromJson<QString>(jo.take("type"_ls)); result.session = - fromJson<QString>(_json.take("session"_ls)); - - result.authInfo = fromJson<QHash<QString, QJsonObject>>(_json); + fromJson<QString>(jo.take("session"_ls)); + + result.authInfo = fromJson<QHash<QString, QJsonObject>>(jo); return result; } diff --git a/lib/csapi/definitions/auth_data.h b/lib/csapi/definitions/auth_data.h index dce55396..661d3e5f 100644 --- a/lib/csapi/definitions/auth_data.h +++ b/lib/csapi/definitions/auth_data.h @@ -26,9 +26,9 @@ namespace QMatrixClient QJsonObject toJson(const AuthenticationData& pod); - template <> struct FromJson<AuthenticationData> + template <> struct FromJsonObject<AuthenticationData> { - AuthenticationData operator()(const QJsonValue& jv); + AuthenticationData operator()(QJsonObject jo) const; }; } // namespace QMatrixClient diff --git a/lib/csapi/definitions/client_device.cpp b/lib/csapi/definitions/client_device.cpp index bd7acd02..4a192f85 100644 --- a/lib/csapi/definitions/client_device.cpp +++ b/lib/csapi/definitions/client_device.cpp @@ -8,27 +8,26 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const Device& pod) { - QJsonObject _json; - addParam<>(_json, QStringLiteral("device_id"), pod.deviceId); - addParam<IfNotEmpty>(_json, QStringLiteral("display_name"), pod.displayName); - addParam<IfNotEmpty>(_json, QStringLiteral("last_seen_ip"), pod.lastSeenIp); - addParam<IfNotEmpty>(_json, QStringLiteral("last_seen_ts"), pod.lastSeenTs); - return _json; + QJsonObject jo; + 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); + return jo; } -Device FromJson<Device>::operator()(const QJsonValue& jv) +Device FromJsonObject<Device>::operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); Device result; result.deviceId = - fromJson<QString>(_json.value("device_id"_ls)); + fromJson<QString>(jo.value("device_id"_ls)); result.displayName = - fromJson<QString>(_json.value("display_name"_ls)); + fromJson<QString>(jo.value("display_name"_ls)); result.lastSeenIp = - fromJson<QString>(_json.value("last_seen_ip"_ls)); + fromJson<QString>(jo.value("last_seen_ip"_ls)); result.lastSeenTs = - fromJson<qint64>(_json.value("last_seen_ts"_ls)); - + fromJson<qint64>(jo.value("last_seen_ts"_ls)); + return result; } diff --git a/lib/csapi/definitions/client_device.h b/lib/csapi/definitions/client_device.h index ba65483d..9f10888a 100644 --- a/lib/csapi/definitions/client_device.h +++ b/lib/csapi/definitions/client_device.h @@ -31,9 +31,9 @@ namespace QMatrixClient QJsonObject toJson(const Device& pod); - template <> struct FromJson<Device> + template <> struct FromJsonObject<Device> { - Device operator()(const QJsonValue& jv); + Device operator()(const QJsonObject& jo) const; }; } // namespace QMatrixClient diff --git a/lib/csapi/definitions/device_keys.cpp b/lib/csapi/definitions/device_keys.cpp index d17f4c12..a0e0ca42 100644 --- a/lib/csapi/definitions/device_keys.cpp +++ b/lib/csapi/definitions/device_keys.cpp @@ -8,30 +8,29 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const DeviceKeys& pod) { - QJsonObject _json; - addParam<>(_json, QStringLiteral("user_id"), pod.userId); - addParam<>(_json, QStringLiteral("device_id"), pod.deviceId); - addParam<>(_json, QStringLiteral("algorithms"), pod.algorithms); - addParam<>(_json, QStringLiteral("keys"), pod.keys); - addParam<>(_json, QStringLiteral("signatures"), pod.signatures); - return _json; + QJsonObject jo; + 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); + return jo; } -DeviceKeys FromJson<DeviceKeys>::operator()(const QJsonValue& jv) +DeviceKeys FromJsonObject<DeviceKeys>::operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); DeviceKeys result; result.userId = - fromJson<QString>(_json.value("user_id"_ls)); + fromJson<QString>(jo.value("user_id"_ls)); result.deviceId = - fromJson<QString>(_json.value("device_id"_ls)); + fromJson<QString>(jo.value("device_id"_ls)); result.algorithms = - fromJson<QStringList>(_json.value("algorithms"_ls)); + fromJson<QStringList>(jo.value("algorithms"_ls)); result.keys = - fromJson<QHash<QString, QString>>(_json.value("keys"_ls)); + fromJson<QHash<QString, QString>>(jo.value("keys"_ls)); result.signatures = - fromJson<QHash<QString, QHash<QString, QString>>>(_json.value("signatures"_ls)); - + fromJson<QHash<QString, QHash<QString, QString>>>(jo.value("signatures"_ls)); + return result; } diff --git a/lib/csapi/definitions/device_keys.h b/lib/csapi/definitions/device_keys.h index 4b223609..6023e7e8 100644 --- a/lib/csapi/definitions/device_keys.h +++ b/lib/csapi/definitions/device_keys.h @@ -37,9 +37,9 @@ namespace QMatrixClient QJsonObject toJson(const DeviceKeys& pod); - template <> struct FromJson<DeviceKeys> + template <> struct FromJsonObject<DeviceKeys> { - DeviceKeys operator()(const QJsonValue& jv); + DeviceKeys operator()(const QJsonObject& jo) const; }; } // namespace QMatrixClient diff --git a/lib/csapi/definitions/event_filter.cpp b/lib/csapi/definitions/event_filter.cpp index 336de0dd..cc444db0 100644 --- a/lib/csapi/definitions/event_filter.cpp +++ b/lib/csapi/definitions/event_filter.cpp @@ -6,32 +6,31 @@ using namespace QMatrixClient; -QJsonObject QMatrixClient::toJson(const Filter& pod) +QJsonObject QMatrixClient::toJson(const EventFilter& pod) { - QJsonObject _json; - addParam<IfNotEmpty>(_json, QStringLiteral("limit"), pod.limit); - addParam<IfNotEmpty>(_json, QStringLiteral("not_senders"), pod.notSenders); - addParam<IfNotEmpty>(_json, QStringLiteral("not_types"), pod.notTypes); - addParam<IfNotEmpty>(_json, QStringLiteral("senders"), pod.senders); - addParam<IfNotEmpty>(_json, QStringLiteral("types"), pod.types); - return _json; + QJsonObject jo; + 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); + return jo; } -Filter FromJson<Filter>::operator()(const QJsonValue& jv) +EventFilter FromJsonObject<EventFilter>::operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); - Filter result; + EventFilter result; result.limit = - fromJson<int>(_json.value("limit"_ls)); + fromJson<int>(jo.value("limit"_ls)); result.notSenders = - fromJson<QStringList>(_json.value("not_senders"_ls)); + fromJson<QStringList>(jo.value("not_senders"_ls)); result.notTypes = - fromJson<QStringList>(_json.value("not_types"_ls)); + fromJson<QStringList>(jo.value("not_types"_ls)); result.senders = - fromJson<QStringList>(_json.value("senders"_ls)); + fromJson<QStringList>(jo.value("senders"_ls)); result.types = - fromJson<QStringList>(_json.value("types"_ls)); - + fromJson<QStringList>(jo.value("types"_ls)); + return result; } diff --git a/lib/csapi/definitions/event_filter.h b/lib/csapi/definitions/event_filter.h index 76f08319..5c6a5b27 100644 --- a/lib/csapi/definitions/event_filter.h +++ b/lib/csapi/definitions/event_filter.h @@ -12,7 +12,7 @@ namespace QMatrixClient { // Data structures - struct Filter + struct EventFilter { /// The maximum number of events to return. Omittable<int> limit; @@ -26,11 +26,11 @@ namespace QMatrixClient QStringList types; }; - QJsonObject toJson(const Filter& pod); + QJsonObject toJson(const EventFilter& pod); - template <> struct FromJson<Filter> + template <> struct FromJsonObject<EventFilter> { - Filter operator()(const QJsonValue& jv); + EventFilter operator()(const QJsonObject& jo) const; }; } // namespace QMatrixClient diff --git a/lib/csapi/definitions/public_rooms_response.cpp b/lib/csapi/definitions/public_rooms_response.cpp index 7cdf16af..2f52501d 100644 --- a/lib/csapi/definitions/public_rooms_response.cpp +++ b/lib/csapi/definitions/public_rooms_response.cpp @@ -8,68 +8,66 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const PublicRoomsChunk& pod) { - QJsonObject _json; - addParam<IfNotEmpty>(_json, QStringLiteral("aliases"), pod.aliases); - addParam<IfNotEmpty>(_json, QStringLiteral("canonical_alias"), pod.canonicalAlias); - addParam<IfNotEmpty>(_json, QStringLiteral("name"), pod.name); - addParam<>(_json, QStringLiteral("num_joined_members"), pod.numJoinedMembers); - addParam<>(_json, QStringLiteral("room_id"), pod.roomId); - addParam<IfNotEmpty>(_json, QStringLiteral("topic"), pod.topic); - addParam<>(_json, QStringLiteral("world_readable"), pod.worldReadable); - addParam<>(_json, QStringLiteral("guest_can_join"), pod.guestCanJoin); - addParam<IfNotEmpty>(_json, QStringLiteral("avatar_url"), pod.avatarUrl); - return _json; + QJsonObject jo; + addParam<IfNotEmpty>(jo, QStringLiteral("aliases"), pod.aliases); + 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); + addParam<IfNotEmpty>(jo, QStringLiteral("topic"), pod.topic); + addParam<>(jo, QStringLiteral("world_readable"), pod.worldReadable); + addParam<>(jo, QStringLiteral("guest_can_join"), pod.guestCanJoin); + addParam<IfNotEmpty>(jo, QStringLiteral("avatar_url"), pod.avatarUrl); + return jo; } -PublicRoomsChunk FromJson<PublicRoomsChunk>::operator()(const QJsonValue& jv) +PublicRoomsChunk FromJsonObject<PublicRoomsChunk>::operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); PublicRoomsChunk result; result.aliases = - fromJson<QStringList>(_json.value("aliases"_ls)); + fromJson<QStringList>(jo.value("aliases"_ls)); result.canonicalAlias = - fromJson<QString>(_json.value("canonical_alias"_ls)); + fromJson<QString>(jo.value("canonical_alias"_ls)); result.name = - fromJson<QString>(_json.value("name"_ls)); + fromJson<QString>(jo.value("name"_ls)); result.numJoinedMembers = - fromJson<qint64>(_json.value("num_joined_members"_ls)); + fromJson<int>(jo.value("num_joined_members"_ls)); result.roomId = - fromJson<QString>(_json.value("room_id"_ls)); + fromJson<QString>(jo.value("room_id"_ls)); result.topic = - fromJson<QString>(_json.value("topic"_ls)); + fromJson<QString>(jo.value("topic"_ls)); result.worldReadable = - fromJson<bool>(_json.value("world_readable"_ls)); + fromJson<bool>(jo.value("world_readable"_ls)); result.guestCanJoin = - fromJson<bool>(_json.value("guest_can_join"_ls)); + fromJson<bool>(jo.value("guest_can_join"_ls)); result.avatarUrl = - fromJson<QString>(_json.value("avatar_url"_ls)); - + fromJson<QString>(jo.value("avatar_url"_ls)); + return result; } QJsonObject QMatrixClient::toJson(const PublicRoomsResponse& pod) { - QJsonObject _json; - addParam<>(_json, QStringLiteral("chunk"), pod.chunk); - addParam<IfNotEmpty>(_json, QStringLiteral("next_batch"), pod.nextBatch); - addParam<IfNotEmpty>(_json, QStringLiteral("prev_batch"), pod.prevBatch); - addParam<IfNotEmpty>(_json, QStringLiteral("total_room_count_estimate"), pod.totalRoomCountEstimate); - return _json; + QJsonObject jo; + 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); + return jo; } -PublicRoomsResponse FromJson<PublicRoomsResponse>::operator()(const QJsonValue& jv) +PublicRoomsResponse FromJsonObject<PublicRoomsResponse>::operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); PublicRoomsResponse result; result.chunk = - fromJson<QVector<PublicRoomsChunk>>(_json.value("chunk"_ls)); + fromJson<QVector<PublicRoomsChunk>>(jo.value("chunk"_ls)); result.nextBatch = - fromJson<QString>(_json.value("next_batch"_ls)); + fromJson<QString>(jo.value("next_batch"_ls)); result.prevBatch = - fromJson<QString>(_json.value("prev_batch"_ls)); + fromJson<QString>(jo.value("prev_batch"_ls)); result.totalRoomCountEstimate = - fromJson<qint64>(_json.value("total_room_count_estimate"_ls)); - + fromJson<int>(jo.value("total_room_count_estimate"_ls)); + return result; } diff --git a/lib/csapi/definitions/public_rooms_response.h b/lib/csapi/definitions/public_rooms_response.h index eea4bc5e..88c805ba 100644 --- a/lib/csapi/definitions/public_rooms_response.h +++ b/lib/csapi/definitions/public_rooms_response.h @@ -22,7 +22,7 @@ namespace QMatrixClient /// The name of the room, if any. QString name; /// The number of members joined to the room. - qint64 numJoinedMembers; + int numJoinedMembers; /// The ID of the room. QString roomId; /// The topic of the room, if any. @@ -39,9 +39,9 @@ namespace QMatrixClient QJsonObject toJson(const PublicRoomsChunk& pod); - template <> struct FromJson<PublicRoomsChunk> + template <> struct FromJsonObject<PublicRoomsChunk> { - PublicRoomsChunk operator()(const QJsonValue& jv); + PublicRoomsChunk operator()(const QJsonObject& jo) const; }; /// A list of the rooms on the server. @@ -59,14 +59,14 @@ namespace QMatrixClient QString prevBatch; /// An estimate on the total number of public rooms, if the /// server has an estimate. - Omittable<qint64> totalRoomCountEstimate; + Omittable<int> totalRoomCountEstimate; }; QJsonObject toJson(const PublicRoomsResponse& pod); - template <> struct FromJson<PublicRoomsResponse> + template <> struct FromJsonObject<PublicRoomsResponse> { - PublicRoomsResponse operator()(const QJsonValue& jv); + PublicRoomsResponse operator()(const QJsonObject& jo) const; }; } // namespace QMatrixClient diff --git a/lib/csapi/definitions/push_condition.cpp b/lib/csapi/definitions/push_condition.cpp index 19351ae1..045094bc 100644 --- a/lib/csapi/definitions/push_condition.cpp +++ b/lib/csapi/definitions/push_condition.cpp @@ -8,27 +8,26 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const PushCondition& pod) { - QJsonObject _json; - addParam<>(_json, QStringLiteral("kind"), pod.kind); - addParam<IfNotEmpty>(_json, QStringLiteral("key"), pod.key); - addParam<IfNotEmpty>(_json, QStringLiteral("pattern"), pod.pattern); - addParam<IfNotEmpty>(_json, QStringLiteral("is"), pod.is); - return _json; + QJsonObject jo; + 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); + return jo; } -PushCondition FromJson<PushCondition>::operator()(const QJsonValue& jv) +PushCondition FromJsonObject<PushCondition>::operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); PushCondition result; result.kind = - fromJson<QString>(_json.value("kind"_ls)); + fromJson<QString>(jo.value("kind"_ls)); result.key = - fromJson<QString>(_json.value("key"_ls)); + fromJson<QString>(jo.value("key"_ls)); result.pattern = - fromJson<QString>(_json.value("pattern"_ls)); + fromJson<QString>(jo.value("pattern"_ls)); result.is = - fromJson<QString>(_json.value("is"_ls)); - + fromJson<QString>(jo.value("is"_ls)); + return result; } diff --git a/lib/csapi/definitions/push_condition.h b/lib/csapi/definitions/push_condition.h index 99d7083c..defcebb3 100644 --- a/lib/csapi/definitions/push_condition.h +++ b/lib/csapi/definitions/push_condition.h @@ -31,9 +31,9 @@ namespace QMatrixClient QJsonObject toJson(const PushCondition& pod); - template <> struct FromJson<PushCondition> + template <> struct FromJsonObject<PushCondition> { - PushCondition operator()(const QJsonValue& jv); + PushCondition operator()(const QJsonObject& jo) const; }; } // namespace QMatrixClient diff --git a/lib/csapi/definitions/push_rule.cpp b/lib/csapi/definitions/push_rule.cpp index 833135ec..baddd187 100644 --- a/lib/csapi/definitions/push_rule.cpp +++ b/lib/csapi/definitions/push_rule.cpp @@ -8,33 +8,32 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const PushRule& pod) { - QJsonObject _json; - addParam<>(_json, QStringLiteral("actions"), pod.actions); - addParam<>(_json, QStringLiteral("default"), pod.isDefault); - addParam<>(_json, QStringLiteral("enabled"), pod.enabled); - addParam<>(_json, QStringLiteral("rule_id"), pod.ruleId); - addParam<IfNotEmpty>(_json, QStringLiteral("conditions"), pod.conditions); - addParam<IfNotEmpty>(_json, QStringLiteral("pattern"), pod.pattern); - return _json; + QJsonObject jo; + addParam<>(jo, QStringLiteral("actions"), pod.actions); + addParam<>(jo, QStringLiteral("default"), pod.isDefault); + addParam<>(jo, QStringLiteral("enabled"), pod.enabled); + addParam<>(jo, QStringLiteral("rule_id"), pod.ruleId); + addParam<IfNotEmpty>(jo, QStringLiteral("conditions"), pod.conditions); + addParam<IfNotEmpty>(jo, QStringLiteral("pattern"), pod.pattern); + return jo; } -PushRule FromJson<PushRule>::operator()(const QJsonValue& jv) +PushRule FromJsonObject<PushRule>::operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); PushRule result; result.actions = - fromJson<QVector<QVariant>>(_json.value("actions"_ls)); + fromJson<QVector<QVariant>>(jo.value("actions"_ls)); result.isDefault = - fromJson<bool>(_json.value("default"_ls)); + fromJson<bool>(jo.value("default"_ls)); result.enabled = - fromJson<bool>(_json.value("enabled"_ls)); + fromJson<bool>(jo.value("enabled"_ls)); result.ruleId = - fromJson<QString>(_json.value("rule_id"_ls)); + fromJson<QString>(jo.value("rule_id"_ls)); result.conditions = - fromJson<QVector<PushCondition>>(_json.value("conditions"_ls)); + fromJson<QVector<PushCondition>>(jo.value("conditions"_ls)); result.pattern = - fromJson<QString>(_json.value("pattern"_ls)); - + fromJson<QString>(jo.value("pattern"_ls)); + return result; } diff --git a/lib/csapi/definitions/push_rule.h b/lib/csapi/definitions/push_rule.h index c6542aa6..5f52876d 100644 --- a/lib/csapi/definitions/push_rule.h +++ b/lib/csapi/definitions/push_rule.h @@ -37,9 +37,9 @@ namespace QMatrixClient QJsonObject toJson(const PushRule& pod); - template <> struct FromJson<PushRule> + template <> struct FromJsonObject<PushRule> { - PushRule operator()(const QJsonValue& jv); + PushRule operator()(const QJsonObject& jo) const; }; } // namespace QMatrixClient diff --git a/lib/csapi/definitions/push_ruleset.cpp b/lib/csapi/definitions/push_ruleset.cpp index c424f686..14b7a4b6 100644 --- a/lib/csapi/definitions/push_ruleset.cpp +++ b/lib/csapi/definitions/push_ruleset.cpp @@ -8,30 +8,29 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const PushRuleset& pod) { - QJsonObject _json; - addParam<IfNotEmpty>(_json, QStringLiteral("content"), pod.content); - addParam<IfNotEmpty>(_json, QStringLiteral("override"), pod.override); - addParam<IfNotEmpty>(_json, QStringLiteral("room"), pod.room); - addParam<IfNotEmpty>(_json, QStringLiteral("sender"), pod.sender); - addParam<IfNotEmpty>(_json, QStringLiteral("underride"), pod.underride); - return _json; + QJsonObject jo; + 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); + return jo; } -PushRuleset FromJson<PushRuleset>::operator()(const QJsonValue& jv) +PushRuleset FromJsonObject<PushRuleset>::operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); PushRuleset result; result.content = - fromJson<QVector<PushRule>>(_json.value("content"_ls)); + fromJson<QVector<PushRule>>(jo.value("content"_ls)); result.override = - fromJson<QVector<PushRule>>(_json.value("override"_ls)); + fromJson<QVector<PushRule>>(jo.value("override"_ls)); result.room = - fromJson<QVector<PushRule>>(_json.value("room"_ls)); + fromJson<QVector<PushRule>>(jo.value("room"_ls)); result.sender = - fromJson<QVector<PushRule>>(_json.value("sender"_ls)); + fromJson<QVector<PushRule>>(jo.value("sender"_ls)); result.underride = - fromJson<QVector<PushRule>>(_json.value("underride"_ls)); - + fromJson<QVector<PushRule>>(jo.value("underride"_ls)); + return result; } diff --git a/lib/csapi/definitions/push_ruleset.h b/lib/csapi/definitions/push_ruleset.h index a5e9ff2c..a274b72a 100644 --- a/lib/csapi/definitions/push_ruleset.h +++ b/lib/csapi/definitions/push_ruleset.h @@ -25,9 +25,9 @@ namespace QMatrixClient QJsonObject toJson(const PushRuleset& pod); - template <> struct FromJson<PushRuleset> + template <> struct FromJsonObject<PushRuleset> { - PushRuleset operator()(const QJsonValue& jv); + PushRuleset operator()(const QJsonObject& jo) const; }; } // namespace QMatrixClient diff --git a/lib/csapi/definitions/room_event_filter.cpp b/lib/csapi/definitions/room_event_filter.cpp index 18ce07ec..f6f1e5cb 100644 --- a/lib/csapi/definitions/room_event_filter.cpp +++ b/lib/csapi/definitions/room_event_filter.cpp @@ -8,24 +8,23 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const RoomEventFilter& pod) { - QJsonObject _json; - addParam<IfNotEmpty>(_json, QStringLiteral("not_rooms"), pod.notRooms); - addParam<IfNotEmpty>(_json, QStringLiteral("rooms"), pod.rooms); - addParam<IfNotEmpty>(_json, QStringLiteral("contains_url"), pod.containsUrl); - return _json; + QJsonObject jo; + addParam<IfNotEmpty>(jo, QStringLiteral("not_rooms"), pod.notRooms); + addParam<IfNotEmpty>(jo, QStringLiteral("rooms"), pod.rooms); + addParam<IfNotEmpty>(jo, QStringLiteral("contains_url"), pod.containsUrl); + return jo; } -RoomEventFilter FromJson<RoomEventFilter>::operator()(const QJsonValue& jv) +RoomEventFilter FromJsonObject<RoomEventFilter>::operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); RoomEventFilter result; result.notRooms = - fromJson<QStringList>(_json.value("not_rooms"_ls)); + fromJson<QStringList>(jo.value("not_rooms"_ls)); result.rooms = - fromJson<QStringList>(_json.value("rooms"_ls)); + fromJson<QStringList>(jo.value("rooms"_ls)); result.containsUrl = - fromJson<bool>(_json.value("contains_url"_ls)); - + fromJson<bool>(jo.value("contains_url"_ls)); + return result; } diff --git a/lib/csapi/definitions/room_event_filter.h b/lib/csapi/definitions/room_event_filter.h index 3252af30..697fe661 100644 --- a/lib/csapi/definitions/room_event_filter.h +++ b/lib/csapi/definitions/room_event_filter.h @@ -13,21 +13,21 @@ namespace QMatrixClient { // Data structures - struct RoomEventFilter : Filter + 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 ``true``, includes only events with a ``url`` key in their content. If ``false``, excludes those events. Defaults to ``false``. bool containsUrl; }; QJsonObject toJson(const RoomEventFilter& pod); - template <> struct FromJson<RoomEventFilter> + template <> struct FromJsonObject<RoomEventFilter> { - RoomEventFilter operator()(const QJsonValue& jv); + RoomEventFilter operator()(const QJsonObject& jo) const; }; } // namespace QMatrixClient diff --git a/lib/csapi/definitions/sync_filter.cpp b/lib/csapi/definitions/sync_filter.cpp index b42f15f5..bd87804c 100644 --- a/lib/csapi/definitions/sync_filter.cpp +++ b/lib/csapi/definitions/sync_filter.cpp @@ -8,65 +8,63 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const RoomFilter& pod) { - QJsonObject _json; - addParam<IfNotEmpty>(_json, QStringLiteral("not_rooms"), pod.notRooms); - addParam<IfNotEmpty>(_json, QStringLiteral("rooms"), pod.rooms); - addParam<IfNotEmpty>(_json, QStringLiteral("ephemeral"), pod.ephemeral); - addParam<IfNotEmpty>(_json, QStringLiteral("include_leave"), pod.includeLeave); - addParam<IfNotEmpty>(_json, QStringLiteral("state"), pod.state); - addParam<IfNotEmpty>(_json, QStringLiteral("timeline"), pod.timeline); - addParam<IfNotEmpty>(_json, QStringLiteral("account_data"), pod.accountData); - return _json; + QJsonObject jo; + addParam<IfNotEmpty>(jo, QStringLiteral("not_rooms"), pod.notRooms); + addParam<IfNotEmpty>(jo, QStringLiteral("rooms"), pod.rooms); + addParam<IfNotEmpty>(jo, QStringLiteral("ephemeral"), pod.ephemeral); + addParam<IfNotEmpty>(jo, QStringLiteral("include_leave"), pod.includeLeave); + addParam<IfNotEmpty>(jo, QStringLiteral("state"), pod.state); + addParam<IfNotEmpty>(jo, QStringLiteral("timeline"), pod.timeline); + addParam<IfNotEmpty>(jo, QStringLiteral("account_data"), pod.accountData); + return jo; } -RoomFilter FromJson<RoomFilter>::operator()(const QJsonValue& jv) +RoomFilter FromJsonObject<RoomFilter>::operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); RoomFilter result; result.notRooms = - fromJson<QStringList>(_json.value("not_rooms"_ls)); + fromJson<QStringList>(jo.value("not_rooms"_ls)); result.rooms = - fromJson<QStringList>(_json.value("rooms"_ls)); + fromJson<QStringList>(jo.value("rooms"_ls)); result.ephemeral = - fromJson<RoomEventFilter>(_json.value("ephemeral"_ls)); + fromJson<RoomEventFilter>(jo.value("ephemeral"_ls)); result.includeLeave = - fromJson<bool>(_json.value("include_leave"_ls)); + fromJson<bool>(jo.value("include_leave"_ls)); result.state = - fromJson<RoomEventFilter>(_json.value("state"_ls)); + fromJson<RoomEventFilter>(jo.value("state"_ls)); result.timeline = - fromJson<RoomEventFilter>(_json.value("timeline"_ls)); + fromJson<RoomEventFilter>(jo.value("timeline"_ls)); result.accountData = - fromJson<RoomEventFilter>(_json.value("account_data"_ls)); - + fromJson<RoomEventFilter>(jo.value("account_data"_ls)); + return result; } -QJsonObject QMatrixClient::toJson(const SyncFilter& pod) +QJsonObject QMatrixClient::toJson(const Filter& pod) { - QJsonObject _json; - addParam<IfNotEmpty>(_json, QStringLiteral("event_fields"), pod.eventFields); - addParam<IfNotEmpty>(_json, QStringLiteral("event_format"), pod.eventFormat); - addParam<IfNotEmpty>(_json, QStringLiteral("presence"), pod.presence); - addParam<IfNotEmpty>(_json, QStringLiteral("account_data"), pod.accountData); - addParam<IfNotEmpty>(_json, QStringLiteral("room"), pod.room); - return _json; + QJsonObject jo; + addParam<IfNotEmpty>(jo, QStringLiteral("event_fields"), pod.eventFields); + addParam<IfNotEmpty>(jo, QStringLiteral("event_format"), pod.eventFormat); + addParam<IfNotEmpty>(jo, QStringLiteral("presence"), pod.presence); + addParam<IfNotEmpty>(jo, QStringLiteral("account_data"), pod.accountData); + addParam<IfNotEmpty>(jo, QStringLiteral("room"), pod.room); + return jo; } -SyncFilter FromJson<SyncFilter>::operator()(const QJsonValue& jv) +Filter FromJsonObject<Filter>::operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); - SyncFilter result; + Filter result; result.eventFields = - fromJson<QStringList>(_json.value("event_fields"_ls)); + fromJson<QStringList>(jo.value("event_fields"_ls)); result.eventFormat = - fromJson<QString>(_json.value("event_format"_ls)); + fromJson<QString>(jo.value("event_format"_ls)); result.presence = - fromJson<Filter>(_json.value("presence"_ls)); + fromJson<EventFilter>(jo.value("presence"_ls)); result.accountData = - fromJson<Filter>(_json.value("account_data"_ls)); + fromJson<EventFilter>(jo.value("account_data"_ls)); result.room = - fromJson<RoomFilter>(_json.value("room"_ls)); - + fromJson<RoomFilter>(jo.value("room"_ls)); + return result; } diff --git a/lib/csapi/definitions/sync_filter.h b/lib/csapi/definitions/sync_filter.h index 7f48f02c..ca275a9a 100644 --- a/lib/csapi/definitions/sync_filter.h +++ b/lib/csapi/definitions/sync_filter.h @@ -35,30 +35,30 @@ namespace QMatrixClient QJsonObject toJson(const RoomFilter& pod); - template <> struct FromJson<RoomFilter> + template <> struct FromJsonObject<RoomFilter> { - RoomFilter operator()(const QJsonValue& jv); + RoomFilter operator()(const QJsonObject& jo) const; }; - struct SyncFilter + 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<Filter> presence; + Omittable<EventFilter> presence; /// The user account data that isn't associated with rooms to include. - Omittable<Filter> accountData; + Omittable<EventFilter> accountData; /// Filters to be applied to room data. Omittable<RoomFilter> room; }; - QJsonObject toJson(const SyncFilter& pod); + QJsonObject toJson(const Filter& pod); - template <> struct FromJson<SyncFilter> + template <> struct FromJsonObject<Filter> { - SyncFilter operator()(const QJsonValue& jv); + Filter operator()(const QJsonObject& jo) const; }; } // namespace QMatrixClient diff --git a/lib/csapi/definitions/user_identifier.cpp b/lib/csapi/definitions/user_identifier.cpp index 3d3acaba..80a6d450 100644 --- a/lib/csapi/definitions/user_identifier.cpp +++ b/lib/csapi/definitions/user_identifier.cpp @@ -8,19 +8,18 @@ using namespace QMatrixClient; QJsonObject QMatrixClient::toJson(const UserIdentifier& pod) { - QJsonObject _json = toJson(pod.additionalProperties); - addParam<>(_json, QStringLiteral("type"), pod.type); - return _json; + QJsonObject jo = toJson(pod.additionalProperties); + addParam<>(jo, QStringLiteral("type"), pod.type); + return jo; } -UserIdentifier FromJson<UserIdentifier>::operator()(const QJsonValue& jv) +UserIdentifier FromJsonObject<UserIdentifier>::operator()(QJsonObject jo) const { - auto _json = jv.toObject(); UserIdentifier result; result.type = - fromJson<QString>(_json.take("type"_ls)); - - result.additionalProperties = fromJson<QVariantHash>(_json); + fromJson<QString>(jo.take("type"_ls)); + + result.additionalProperties = fromJson<QVariantHash>(jo); return result; } diff --git a/lib/csapi/definitions/user_identifier.h b/lib/csapi/definitions/user_identifier.h index edc254d3..42614436 100644 --- a/lib/csapi/definitions/user_identifier.h +++ b/lib/csapi/definitions/user_identifier.h @@ -23,9 +23,9 @@ namespace QMatrixClient QJsonObject toJson(const UserIdentifier& pod); - template <> struct FromJson<UserIdentifier> + template <> struct FromJsonObject<UserIdentifier> { - UserIdentifier operator()(const QJsonValue& jv); + UserIdentifier operator()(QJsonObject jo) const; }; } // namespace QMatrixClient diff --git a/lib/csapi/definitions/wellknown/homeserver.cpp b/lib/csapi/definitions/wellknown/homeserver.cpp new file mode 100644 index 00000000..f1482ee4 --- /dev/null +++ b/lib/csapi/definitions/wellknown/homeserver.cpp @@ -0,0 +1,24 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + +#include "homeserver.h" + +using namespace QMatrixClient; + +QJsonObject QMatrixClient::toJson(const HomeserverInformation& pod) +{ + QJsonObject jo; + addParam<>(jo, QStringLiteral("base_url"), pod.baseUrl); + return jo; +} + +HomeserverInformation FromJsonObject<HomeserverInformation>::operator()(const QJsonObject& jo) const +{ + HomeserverInformation result; + result.baseUrl = + fromJson<QString>(jo.value("base_url"_ls)); + + return result; +} + diff --git a/lib/csapi/definitions/wellknown/homeserver.h b/lib/csapi/definitions/wellknown/homeserver.h new file mode 100644 index 00000000..09d6ba63 --- /dev/null +++ b/lib/csapi/definitions/wellknown/homeserver.h @@ -0,0 +1,28 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + +#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; + }; + + QJsonObject toJson(const HomeserverInformation& pod); + + template <> struct FromJsonObject<HomeserverInformation> + { + HomeserverInformation operator()(const QJsonObject& jo) const; + }; + +} // namespace QMatrixClient diff --git a/lib/csapi/definitions/wellknown/identity_server.cpp b/lib/csapi/definitions/wellknown/identity_server.cpp new file mode 100644 index 00000000..f9d7bc37 --- /dev/null +++ b/lib/csapi/definitions/wellknown/identity_server.cpp @@ -0,0 +1,24 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + +#include "identity_server.h" + +using namespace QMatrixClient; + +QJsonObject QMatrixClient::toJson(const IdentityServerInformation& pod) +{ + QJsonObject jo; + addParam<>(jo, QStringLiteral("base_url"), pod.baseUrl); + return jo; +} + +IdentityServerInformation FromJsonObject<IdentityServerInformation>::operator()(const QJsonObject& jo) const +{ + IdentityServerInformation result; + result.baseUrl = + fromJson<QString>(jo.value("base_url"_ls)); + + return result; +} + diff --git a/lib/csapi/definitions/wellknown/identity_server.h b/lib/csapi/definitions/wellknown/identity_server.h new file mode 100644 index 00000000..cb8ffcee --- /dev/null +++ b/lib/csapi/definitions/wellknown/identity_server.h @@ -0,0 +1,28 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + +#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; + }; + + QJsonObject toJson(const IdentityServerInformation& pod); + + template <> struct FromJsonObject<IdentityServerInformation> + { + IdentityServerInformation operator()(const QJsonObject& jo) const; + }; + +} // namespace QMatrixClient diff --git a/lib/csapi/device_management.cpp b/lib/csapi/device_management.cpp index 4418f6c9..861e1994 100644 --- a/lib/csapi/device_management.cpp +++ b/lib/csapi/device_management.cpp @@ -77,11 +77,7 @@ const Device& GetDeviceJob::data() const BaseJob::Status GetDeviceJob::parseJson(const QJsonDocument& data) { - auto json = data.object(); - if (!json.contains("data"_ls)) - return { JsonParseError, - "The key 'data' not found in the response" }; - d->data = fromJson<Device>(json.value("data"_ls)); + d->data = fromJson<Device>(data); return Success; } diff --git a/lib/csapi/device_management.h b/lib/csapi/device_management.h index 338f8529..f41efdbc 100644 --- a/lib/csapi/device_management.h +++ b/lib/csapi/device_management.h @@ -16,7 +16,7 @@ namespace QMatrixClient // Operations /// List registered devices for the current user - /// + /// /// Gets information about all devices for the current user. class GetDevicesJob : public BaseJob { @@ -47,13 +47,13 @@ namespace QMatrixClient }; /// Get a single device - /// + /// /// Gets information on a single device, by device id. class GetDeviceJob : public BaseJob { public: /*! Get a single device - * \param deviceId + * \param deviceId * The device to retrieve. */ explicit GetDeviceJob(const QString& deviceId); @@ -82,15 +82,15 @@ namespace QMatrixClient }; /// Update a device - /// + /// /// Updates the metadata on the given device. class UpdateDeviceJob : public BaseJob { public: /*! Update a device - * \param deviceId + * \param deviceId * The device to update. - * \param displayName + * \param displayName * The new display name for this device. If not given, the * display name is unchanged. */ @@ -98,7 +98,7 @@ namespace QMatrixClient }; /// Delete a device - /// + /// /// This API endpoint uses the `User-Interactive Authentication API`_. /// /// Deletes the given device, and invalidates any access token associated with it. @@ -106,9 +106,9 @@ namespace QMatrixClient { public: /*! Delete a device - * \param deviceId + * \param deviceId * The device to delete. - * \param auth + * \param auth * Additional authentication information for the * user-interactive authentication API. */ @@ -116,7 +116,7 @@ namespace QMatrixClient }; /// 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. @@ -124,9 +124,9 @@ namespace QMatrixClient { public: /*! Bulk deletion of devices - * \param devices + * \param devices * The list of device IDs to delete. - * \param auth + * \param auth * Additional authentication information for the * user-interactive authentication API. */ diff --git a/lib/csapi/directory.cpp b/lib/csapi/directory.cpp index fd3b8839..5353f3bc 100644 --- a/lib/csapi/directory.cpp +++ b/lib/csapi/directory.cpp @@ -19,7 +19,7 @@ SetRoomAliasJob::SetRoomAliasJob(const QString& roomAlias, const QString& roomId basePath % "/room/" % roomAlias) { QJsonObject _data; - addParam<IfNotEmpty>(_data, QStringLiteral("room_id"), roomId); + addParam<>(_data, QStringLiteral("room_id"), roomId); setRequestData(_data); } diff --git a/lib/csapi/directory.h b/lib/csapi/directory.h index 69069ee0..39e86635 100644 --- a/lib/csapi/directory.h +++ b/lib/csapi/directory.h @@ -16,16 +16,16 @@ namespace QMatrixClient { public: /*! Create a new mapping from room alias to room ID. - * \param roomAlias + * \param roomAlias * The room alias to set. - * \param roomId + * \param roomId * The room ID to set. */ - explicit SetRoomAliasJob(const QString& roomAlias, const QString& roomId = {}); + 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 @@ -35,7 +35,7 @@ namespace QMatrixClient { public: /*! Get the room ID corresponding to this room alias. - * \param roomAlias + * \param roomAlias * The room alias. */ explicit GetRoomIdByAliasJob(const QString& roomAlias); @@ -66,7 +66,7 @@ namespace QMatrixClient }; /// 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. @@ -74,7 +74,7 @@ namespace QMatrixClient { public: /*! Remove a mapping of room alias to room ID. - * \param roomAlias + * \param roomAlias * The room alias to remove. */ explicit DeleteRoomAliasJob(const QString& roomAlias); diff --git a/lib/csapi/event_context.h b/lib/csapi/event_context.h index 41ee202c..a5fda7ea 100644 --- a/lib/csapi/event_context.h +++ b/lib/csapi/event_context.h @@ -14,7 +14,7 @@ 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. @@ -22,11 +22,11 @@ namespace QMatrixClient { public: /*! Get events and state around the specified event. - * \param roomId + * \param roomId * The room to get events from. - * \param eventId + * \param eventId * The event to get context around. - * \param limit + * \param limit * The maximum number of events to return. Default: 10. */ explicit GetEventContextJob(const QString& roomId, const QString& eventId, Omittable<int> limit = none); diff --git a/lib/csapi/filter.cpp b/lib/csapi/filter.cpp index 51056cc3..77dc9b92 100644 --- a/lib/csapi/filter.cpp +++ b/lib/csapi/filter.cpp @@ -20,7 +20,7 @@ class DefineFilterJob::Private static const auto DefineFilterJobName = QStringLiteral("DefineFilterJob"); -DefineFilterJob::DefineFilterJob(const QString& userId, const SyncFilter& filter) +DefineFilterJob::DefineFilterJob(const QString& userId, const Filter& filter) : BaseJob(HttpVerb::Post, DefineFilterJobName, basePath % "/user/" % userId % "/filter") , d(new Private) @@ -38,6 +38,9 @@ const QString& DefineFilterJob::filterId() const BaseJob::Status DefineFilterJob::parseJson(const QJsonDocument& data) { auto json = data.object(); + if (!json.contains("filter_id"_ls)) + return { JsonParseError, + "The key 'filter_id' not found in the response" }; d->filterId = fromJson<QString>(json.value("filter_id"_ls)); return Success; } @@ -45,7 +48,7 @@ BaseJob::Status DefineFilterJob::parseJson(const QJsonDocument& data) class GetFilterJob::Private { public: - SyncFilter data; + Filter data; }; QUrl GetFilterJob::makeRequestUrl(QUrl baseUrl, const QString& userId, const QString& filterId) @@ -65,18 +68,14 @@ GetFilterJob::GetFilterJob(const QString& userId, const QString& filterId) GetFilterJob::~GetFilterJob() = default; -const SyncFilter& GetFilterJob::data() const +const Filter& GetFilterJob::data() const { return d->data; } BaseJob::Status GetFilterJob::parseJson(const QJsonDocument& data) { - auto json = data.object(); - if (!json.contains("data"_ls)) - return { JsonParseError, - "The key 'data' not found in the response" }; - d->data = fromJson<SyncFilter>(json.value("data"_ls)); + d->data = fromJson<Filter>(data); return Success; } diff --git a/lib/csapi/filter.h b/lib/csapi/filter.h index 87583a59..0ca7e953 100644 --- a/lib/csapi/filter.h +++ b/lib/csapi/filter.h @@ -14,7 +14,7 @@ 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. @@ -22,19 +22,22 @@ namespace QMatrixClient { public: /*! Upload a new filter. - * \param userId + * \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 + * \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 SyncFilter& filter); + explicit DefineFilterJob(const QString& userId, const Filter& filter); ~DefineFilterJob() override; // Result properties - /// The ID of the filter that was created. + /// 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: @@ -50,9 +53,9 @@ namespace QMatrixClient { public: /*! Download a filter - * \param userId + * \param userId * The user ID to download a filter for. - * \param filterId + * \param filterId * The filter ID to download. */ explicit GetFilterJob(const QString& userId, const QString& filterId); @@ -70,7 +73,7 @@ namespace QMatrixClient // Result properties /// "The filter defintion" - const SyncFilter& data() const; + const Filter& data() const; protected: Status parseJson(const QJsonDocument& data) override; diff --git a/lib/csapi/gtad.yaml b/lib/csapi/gtad.yaml index 31dd6a83..cb5e553c 100644 --- a/lib/csapi/gtad.yaml +++ b/lib/csapi/gtad.yaml @@ -9,6 +9,8 @@ analyzer: origin_server_ts: originServerTimestamp # Instead of originServerTs start: begin # Because start() is a method in BaseJob m.upload.size: uploadSize + m.homeserver: homeserver + m.identity_server: identityServer AuthenticationData/additionalProperties: authInfo # Structure inside `types`: diff --git a/lib/csapi/inviting.h b/lib/csapi/inviting.h index 41283817..6d5d2e99 100644 --- a/lib/csapi/inviting.h +++ b/lib/csapi/inviting.h @@ -12,7 +12,7 @@ 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. @@ -35,9 +35,9 @@ namespace QMatrixClient { public: /*! Invite a user to participate in a particular room. - * \param roomId + * \param roomId * The room identifier (not alias) to which to invite the user. - * \param userId + * \param userId * The fully qualified user ID of the invitee. */ explicit InviteUserJob(const QString& roomId, const QString& userId); diff --git a/lib/csapi/joining.cpp b/lib/csapi/joining.cpp index 1a29ac62..71781154 100644 --- a/lib/csapi/joining.cpp +++ b/lib/csapi/joining.cpp @@ -18,12 +18,12 @@ namespace QMatrixClient QJsonObject toJson(const JoinRoomByIdJob::ThirdPartySigned& pod) { - QJsonObject _json; - addParam<>(_json, QStringLiteral("sender"), pod.sender); - addParam<>(_json, QStringLiteral("mxid"), pod.mxid); - addParam<>(_json, QStringLiteral("token"), pod.token); - addParam<>(_json, QStringLiteral("signatures"), pod.signatures); - return _json; + QJsonObject jo; + addParam<>(jo, QStringLiteral("sender"), pod.sender); + addParam<>(jo, QStringLiteral("mxid"), pod.mxid); + addParam<>(jo, QStringLiteral("token"), pod.token); + addParam<>(jo, QStringLiteral("signatures"), pod.signatures); + return jo; } } // namespace QMatrixClient @@ -68,19 +68,19 @@ namespace QMatrixClient QJsonObject toJson(const JoinRoomJob::Signed& pod) { - QJsonObject _json; - addParam<>(_json, QStringLiteral("sender"), pod.sender); - addParam<>(_json, QStringLiteral("mxid"), pod.mxid); - addParam<>(_json, QStringLiteral("token"), pod.token); - addParam<>(_json, QStringLiteral("signatures"), pod.signatures); - return _json; + QJsonObject jo; + addParam<>(jo, QStringLiteral("sender"), pod.sender); + addParam<>(jo, QStringLiteral("mxid"), pod.mxid); + addParam<>(jo, QStringLiteral("token"), pod.token); + addParam<>(jo, QStringLiteral("signatures"), pod.signatures); + return jo; } QJsonObject toJson(const JoinRoomJob::ThirdPartySigned& pod) { - QJsonObject _json; - addParam<>(_json, QStringLiteral("signed"), pod.signedData); - return _json; + QJsonObject jo; + addParam<>(jo, QStringLiteral("signed"), pod.signedData); + return jo; } } // namespace QMatrixClient diff --git a/lib/csapi/joining.h b/lib/csapi/joining.h index a73b1896..137afbfc 100644 --- a/lib/csapi/joining.h +++ b/lib/csapi/joining.h @@ -14,7 +14,7 @@ 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 @@ -49,9 +49,9 @@ namespace QMatrixClient // Construction/destruction /*! Start the requesting user participating in a particular room. - * \param roomId + * \param roomId * The room identifier (not alias) to join. - * \param thirdPartySigned + * \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); @@ -71,7 +71,7 @@ namespace QMatrixClient }; /// 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 @@ -125,12 +125,12 @@ namespace QMatrixClient // Construction/destruction /*! Start the requesting user participating in a particular room. - * \param roomIdOrAlias + * \param roomIdOrAlias * The room identifier or alias to join. - * \param serverName + * \param serverName * The servers to attempt to join the room through. One of the servers * must be participating in the room. - * \param thirdPartySigned + * \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); diff --git a/lib/csapi/keys.cpp b/lib/csapi/keys.cpp index fac811d0..c7492411 100644 --- a/lib/csapi/keys.cpp +++ b/lib/csapi/keys.cpp @@ -52,27 +52,25 @@ namespace QMatrixClient { // Converters - template <> struct FromJson<QueryKeysJob::UnsignedDeviceInfo> + template <> struct FromJsonObject<QueryKeysJob::UnsignedDeviceInfo> { - QueryKeysJob::UnsignedDeviceInfo operator()(const QJsonValue& jv) + QueryKeysJob::UnsignedDeviceInfo operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); QueryKeysJob::UnsignedDeviceInfo result; result.deviceDisplayName = - fromJson<QString>(_json.value("device_display_name"_ls)); + fromJson<QString>(jo.value("device_display_name"_ls)); return result; } }; - template <> struct FromJson<QueryKeysJob::DeviceInformation> + template <> struct FromJsonObject<QueryKeysJob::DeviceInformation> { - QueryKeysJob::DeviceInformation operator()(const QJsonValue& jv) + QueryKeysJob::DeviceInformation operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); QueryKeysJob::DeviceInformation result; result.unsignedData = - fromJson<QueryKeysJob::UnsignedDeviceInfo>(_json.value("unsigned"_ls)); + fromJson<QueryKeysJob::UnsignedDeviceInfo>(jo.value("unsigned"_ls)); return result; } diff --git a/lib/csapi/keys.h b/lib/csapi/keys.h index 1842b943..e59b1dae 100644 --- a/lib/csapi/keys.h +++ b/lib/csapi/keys.h @@ -17,16 +17,16 @@ namespace QMatrixClient // Operations /// 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 + * \param deviceKeys * Identity keys for the device. May be absent if no new * identity keys are required. - * \param oneTimeKeys + * \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 @@ -52,7 +52,7 @@ namespace QMatrixClient }; /// Download device identity keys. - /// + /// /// Returns the current devices and identity keys for the given users. class QueryKeysJob : public BaseJob { @@ -80,14 +80,14 @@ namespace QMatrixClient // Construction/destruction /*! Download device identity keys. - * \param deviceKeys + * \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 + * \param timeout * The time (in milliseconds) to wait when downloading keys from * remote servers. 10 seconds is the recommended default. - * \param token + * \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 @@ -122,16 +122,16 @@ namespace QMatrixClient }; /// 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 + * \param oneTimeKeys * The keys to be claimed. A map from user ID, to a map from * device ID to algorithm name. - * \param timeout + * \param timeout * The time (in milliseconds) to wait when downloading keys from * remote servers. 10 seconds is the recommended default. */ @@ -161,7 +161,7 @@ namespace QMatrixClient }; /// Query users with recent device key updates. - /// + /// /// Gets a list of users who have updated their device identity keys since a /// previous sync token. /// @@ -175,13 +175,13 @@ namespace QMatrixClient { public: /*! Query users with recent device key updates. - * \param from + * \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 + * \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 diff --git a/lib/csapi/kicking.h b/lib/csapi/kicking.h index dde373b1..5968187e 100644 --- a/lib/csapi/kicking.h +++ b/lib/csapi/kicking.h @@ -12,7 +12,7 @@ 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. @@ -24,12 +24,12 @@ namespace QMatrixClient { public: /*! Kick a user from the room. - * \param roomId + * \param roomId * The room identifier (not alias) from which the user should be kicked. - * \param userId + * \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 + * \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 = {}); diff --git a/lib/csapi/leaving.h b/lib/csapi/leaving.h index 95859627..3a340034 100644 --- a/lib/csapi/leaving.h +++ b/lib/csapi/leaving.h @@ -12,7 +12,7 @@ namespace QMatrixClient // Operations /// 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 @@ -28,7 +28,7 @@ namespace QMatrixClient { public: /*! Stop the requesting user participating in a particular room. - * \param roomId + * \param roomId * The room identifier to leave. */ explicit LeaveRoomJob(const QString& roomId); @@ -44,7 +44,7 @@ namespace QMatrixClient }; /// 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 @@ -58,7 +58,7 @@ namespace QMatrixClient { public: /*! Stop the requesting user remembering about a particular room. - * \param roomId + * \param roomId * The room identifier to forget. */ explicit ForgetRoomJob(const QString& roomId); diff --git a/lib/csapi/list_joined_rooms.h b/lib/csapi/list_joined_rooms.h index 2032265c..881a97b4 100644 --- a/lib/csapi/list_joined_rooms.h +++ b/lib/csapi/list_joined_rooms.h @@ -12,7 +12,7 @@ namespace QMatrixClient // Operations /// Lists the user's current rooms. - /// + /// /// This API returns a list of the user's current rooms. class GetJoinedRoomsJob : public BaseJob { diff --git a/lib/csapi/list_public_rooms.cpp b/lib/csapi/list_public_rooms.cpp index 1a5b9203..2fdb2005 100644 --- a/lib/csapi/list_public_rooms.cpp +++ b/lib/csapi/list_public_rooms.cpp @@ -100,11 +100,7 @@ const PublicRoomsResponse& GetPublicRoomsJob::data() const BaseJob::Status GetPublicRoomsJob::parseJson(const QJsonDocument& data) { - auto json = data.object(); - if (!json.contains("data"_ls)) - return { JsonParseError, - "The key 'data' not found in the response" }; - d->data = fromJson<PublicRoomsResponse>(json.value("data"_ls)); + d->data = fromJson<PublicRoomsResponse>(data); return Success; } @@ -114,48 +110,16 @@ namespace QMatrixClient QJsonObject toJson(const QueryPublicRoomsJob::Filter& pod) { - QJsonObject _json; - addParam<IfNotEmpty>(_json, QStringLiteral("generic_search_term"), pod.genericSearchTerm); - return _json; + QJsonObject jo; + addParam<IfNotEmpty>(jo, QStringLiteral("generic_search_term"), pod.genericSearchTerm); + return jo; } - - template <> struct FromJson<QueryPublicRoomsJob::PublicRoomsChunk> - { - QueryPublicRoomsJob::PublicRoomsChunk operator()(const QJsonValue& jv) - { - const auto& _json = jv.toObject(); - QueryPublicRoomsJob::PublicRoomsChunk result; - result.aliases = - fromJson<QStringList>(_json.value("aliases"_ls)); - result.canonicalAlias = - fromJson<QString>(_json.value("canonical_alias"_ls)); - result.name = - fromJson<QString>(_json.value("name"_ls)); - result.numJoinedMembers = - fromJson<qint64>(_json.value("num_joined_members"_ls)); - result.roomId = - fromJson<QString>(_json.value("room_id"_ls)); - result.topic = - fromJson<QString>(_json.value("topic"_ls)); - result.worldReadable = - fromJson<bool>(_json.value("world_readable"_ls)); - result.guestCanJoin = - fromJson<bool>(_json.value("guest_can_join"_ls)); - result.avatarUrl = - fromJson<QString>(_json.value("avatar_url"_ls)); - - return result; - } - }; } // namespace QMatrixClient class QueryPublicRoomsJob::Private { public: - QVector<PublicRoomsChunk> chunk; - QString nextBatch; - QString prevBatch; - Omittable<qint64> totalRoomCountEstimate; + PublicRoomsResponse data; }; BaseJob::Query queryToQueryPublicRooms(const QString& server) @@ -167,7 +131,7 @@ BaseJob::Query queryToQueryPublicRooms(const QString& server) static const auto QueryPublicRoomsJobName = QStringLiteral("QueryPublicRoomsJob"); -QueryPublicRoomsJob::QueryPublicRoomsJob(const QString& server, Omittable<int> limit, const QString& since, const Omittable<Filter>& filter) +QueryPublicRoomsJob::QueryPublicRoomsJob(const QString& server, Omittable<int> limit, const QString& since, const Omittable<Filter>& filter, bool includeAllNetworks, const QString& thirdPartyInstanceId) : BaseJob(HttpVerb::Post, QueryPublicRoomsJobName, basePath % "/publicRooms", queryToQueryPublicRooms(server)) @@ -177,41 +141,21 @@ QueryPublicRoomsJob::QueryPublicRoomsJob(const QString& server, Omittable<int> l addParam<IfNotEmpty>(_data, QStringLiteral("limit"), limit); addParam<IfNotEmpty>(_data, QStringLiteral("since"), since); addParam<IfNotEmpty>(_data, QStringLiteral("filter"), filter); + addParam<IfNotEmpty>(_data, QStringLiteral("include_all_networks"), includeAllNetworks); + addParam<IfNotEmpty>(_data, QStringLiteral("third_party_instance_id"), thirdPartyInstanceId); setRequestData(_data); } QueryPublicRoomsJob::~QueryPublicRoomsJob() = default; -const QVector<QueryPublicRoomsJob::PublicRoomsChunk>& QueryPublicRoomsJob::chunk() const +const PublicRoomsResponse& QueryPublicRoomsJob::data() const { - return d->chunk; -} - -const QString& QueryPublicRoomsJob::nextBatch() const -{ - return d->nextBatch; -} - -const QString& QueryPublicRoomsJob::prevBatch() const -{ - return d->prevBatch; -} - -Omittable<qint64> QueryPublicRoomsJob::totalRoomCountEstimate() const -{ - return d->totalRoomCountEstimate; + return d->data; } BaseJob::Status QueryPublicRoomsJob::parseJson(const QJsonDocument& data) { - auto json = data.object(); - if (!json.contains("chunk"_ls)) - return { JsonParseError, - "The key 'chunk' not found in the response" }; - d->chunk = fromJson<QVector<PublicRoomsChunk>>(json.value("chunk"_ls)); - d->nextBatch = fromJson<QString>(json.value("next_batch"_ls)); - d->prevBatch = fromJson<QString>(json.value("prev_batch"_ls)); - d->totalRoomCountEstimate = fromJson<qint64>(json.value("total_room_count_estimate"_ls)); + d->data = fromJson<PublicRoomsResponse>(data); return Success; } diff --git a/lib/csapi/list_public_rooms.h b/lib/csapi/list_public_rooms.h index b2697c8c..8401c134 100644 --- a/lib/csapi/list_public_rooms.h +++ b/lib/csapi/list_public_rooms.h @@ -6,7 +6,6 @@ #include "jobs/basejob.h" -#include <QtCore/QVector> #include "csapi/definitions/public_rooms_response.h" #include "converters.h" @@ -15,13 +14,13 @@ namespace QMatrixClient // Operations /// 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 + * \param roomId * The room ID. */ explicit GetRoomVisibilityOnDirectoryJob(const QString& roomId); @@ -50,7 +49,7 @@ 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. /// @@ -61,9 +60,9 @@ namespace QMatrixClient { public: /*! Sets the visibility of a room in the room directory - * \param roomId + * \param roomId * The room ID. - * \param visibility + * \param visibility * The new visibility setting for the room. * Defaults to 'public'. */ @@ -71,7 +70,7 @@ namespace QMatrixClient }; /// 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 @@ -80,14 +79,14 @@ namespace QMatrixClient { public: /*! Lists the public rooms on the server. - * \param limit + * \param limit * Limit the number of results returned. - * \param since + * \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 + * \param server * The server to fetch the public room lists from. Defaults to the * local server. */ @@ -117,7 +116,7 @@ namespace QMatrixClient }; /// 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 @@ -135,68 +134,35 @@ namespace QMatrixClient QString genericSearchTerm; }; - /// 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. - 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. - qint64 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; - }; - // Construction/destruction /*! Lists the public rooms on the server with optional filter. - * \param server + * \param server * The server to fetch the public room lists from. Defaults to the * local server. - * \param limit + * \param limit * Limit the number of results returned. - * \param since + * \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 + * \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); + explicit QueryPublicRoomsJob(const QString& server = {}, Omittable<int> limit = none, const QString& since = {}, const Omittable<Filter>& filter = none, bool includeAllNetworks = false, const QString& thirdPartyInstanceId = {}); ~QueryPublicRoomsJob() override; // Result properties - /// A paginated chunk of public rooms. - const QVector<PublicRoomsChunk>& chunk() const; - /// 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. - const QString& nextBatch() const; - /// 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. - const QString& prevBatch() const; - /// An estimate on the total number of public rooms, if the - /// server has an estimate. - Omittable<qint64> totalRoomCountEstimate() const; + /// A list of the rooms on the server. + const PublicRoomsResponse& data() const; protected: Status parseJson(const QJsonDocument& data) override; diff --git a/lib/csapi/login.cpp b/lib/csapi/login.cpp index 363b6037..4d15a30b 100644 --- a/lib/csapi/login.cpp +++ b/lib/csapi/login.cpp @@ -16,14 +16,13 @@ namespace QMatrixClient { // Converters - template <> struct FromJson<GetLoginFlowsJob::LoginFlow> + template <> struct FromJsonObject<GetLoginFlowsJob::LoginFlow> { - GetLoginFlowsJob::LoginFlow operator()(const QJsonValue& jv) + GetLoginFlowsJob::LoginFlow operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); GetLoginFlowsJob::LoginFlow result; result.type = - fromJson<QString>(_json.value("type"_ls)); + fromJson<QString>(jo.value("type"_ls)); return result; } diff --git a/lib/csapi/login.h b/lib/csapi/login.h index 6b35cb85..957d8881 100644 --- a/lib/csapi/login.h +++ b/lib/csapi/login.h @@ -15,7 +15,7 @@ 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 @@ -60,7 +60,7 @@ namespace QMatrixClient }; /// Authenticates the user. - /// + /// /// Authenticates the user, and issues an access token they can /// use to authorize themself in subsequent requests. /// @@ -75,27 +75,27 @@ namespace QMatrixClient { public: /*! Authenticates the user. - * \param type + * \param type * The login type being used. - * \param identifier + * \param identifier * Identification information for the user. - * \param password + * \param password * Required when ``type`` is ``m.login.password``. The user's * password. - * \param token + * \param token * Required when ``type`` is ``m.login.token``. Part of `Token-based`_ login. - * \param deviceId + * \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 + * \param initialDeviceDisplayName * A display name to assign to the newly-created device. Ignored * if ``device_id`` corresponds to a known device. - * \param user + * \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 + * \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 + * \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 = {}); diff --git a/lib/csapi/logout.h b/lib/csapi/logout.h index f124ac68..3ef3c656 100644 --- a/lib/csapi/logout.h +++ b/lib/csapi/logout.h @@ -12,7 +12,7 @@ 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 @@ -31,7 +31,7 @@ namespace QMatrixClient }; /// 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. /// diff --git a/lib/csapi/message_pagination.h b/lib/csapi/message_pagination.h index 890f3ac8..12544f0c 100644 --- a/lib/csapi/message_pagination.h +++ b/lib/csapi/message_pagination.h @@ -14,30 +14,30 @@ 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 + * \param roomId * The room to get events from. - * \param 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 + * \param dir * The direction to return events from. - * \param to + * \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 + * \param limit * The maximum number of events to return. Default: 10. - * \param filter + * \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 = {}); diff --git a/lib/csapi/notifications.cpp b/lib/csapi/notifications.cpp index f98cddd2..785a0a8a 100644 --- a/lib/csapi/notifications.cpp +++ b/lib/csapi/notifications.cpp @@ -16,24 +16,23 @@ namespace QMatrixClient { // Converters - template <> struct FromJson<GetNotificationsJob::Notification> + template <> struct FromJsonObject<GetNotificationsJob::Notification> { - GetNotificationsJob::Notification operator()(const QJsonValue& jv) + GetNotificationsJob::Notification operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); GetNotificationsJob::Notification result; result.actions = - fromJson<QVector<QVariant>>(_json.value("actions"_ls)); + fromJson<QVector<QVariant>>(jo.value("actions"_ls)); result.event = - fromJson<EventPtr>(_json.value("event"_ls)); + fromJson<EventPtr>(jo.value("event"_ls)); result.profileTag = - fromJson<QString>(_json.value("profile_tag"_ls)); + fromJson<QString>(jo.value("profile_tag"_ls)); result.read = - fromJson<bool>(_json.value("read"_ls)); + fromJson<bool>(jo.value("read"_ls)); result.roomId = - fromJson<QString>(_json.value("room_id"_ls)); + fromJson<QString>(jo.value("room_id"_ls)); result.ts = - fromJson<qint64>(_json.value("ts"_ls)); + fromJson<int>(jo.value("ts"_ls)); return result; } diff --git a/lib/csapi/notifications.h b/lib/csapi/notifications.h index 4edb9c3e..898b5154 100644 --- a/lib/csapi/notifications.h +++ b/lib/csapi/notifications.h @@ -17,7 +17,7 @@ namespace QMatrixClient // 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 @@ -43,17 +43,17 @@ namespace QMatrixClient QString roomId; /// The unix timestamp at which the event notification was sent, /// in milliseconds. - qint64 ts; + int ts; }; // Construction/destruction /*! Gets a list of events that the user has been notified about - * \param from + * \param from * Pagination token given to retrieve the next set of events. - * \param limit + * \param limit * Limit on the number of events to return in this request. - * \param only + * \param only * Allows basic filtering of events returned. Supply ``highlight`` * to return only events where the notification had the highlight * tweak set. diff --git a/lib/csapi/openid.h b/lib/csapi/openid.h index 0dbad7eb..807801fb 100644 --- a/lib/csapi/openid.h +++ b/lib/csapi/openid.h @@ -14,7 +14,7 @@ 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 @@ -27,10 +27,10 @@ namespace QMatrixClient { public: /*! Get an OpenID token object to verify the requester's identity. - * \param userId + * \param userId * The user to request and OpenID token for. Should be the user who * is authenticated for the request. - * \param body + * \param body * An empty object. Reserved for future expansion. */ explicit RequestOpenIdTokenJob(const QString& userId, const QJsonObject& body = {}); diff --git a/lib/csapi/peeking_events.h b/lib/csapi/peeking_events.h index f8e8b966..5a6e513c 100644 --- a/lib/csapi/peeking_events.h +++ b/lib/csapi/peeking_events.h @@ -14,7 +14,7 @@ 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. @@ -29,12 +29,12 @@ namespace QMatrixClient { public: /*! Listen on the event stream. - * \param from + * \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 + * \param timeout * The maximum time in milliseconds to wait for an event. - * \param roomId + * \param roomId * The room ID for which events should be returned. */ explicit PeekEventsJob(const QString& from = {}, Omittable<int> timeout = none, const QString& roomId = {}); diff --git a/lib/csapi/presence.cpp b/lib/csapi/presence.cpp index ca4c850e..7aba8b61 100644 --- a/lib/csapi/presence.cpp +++ b/lib/csapi/presence.cpp @@ -125,11 +125,7 @@ Events&& GetPresenceForListJob::data() BaseJob::Status GetPresenceForListJob::parseJson(const QJsonDocument& data) { - auto json = data.object(); - if (!json.contains("data"_ls)) - return { JsonParseError, - "The key 'data' not found in the response" }; - d->data = fromJson<Events>(json.value("data"_ls)); + d->data = fromJson<Events>(data); return Success; } diff --git a/lib/csapi/presence.h b/lib/csapi/presence.h index 74380ed1..86b9d395 100644 --- a/lib/csapi/presence.h +++ b/lib/csapi/presence.h @@ -14,7 +14,7 @@ namespace QMatrixClient // 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 @@ -23,24 +23,24 @@ namespace QMatrixClient { public: /*! Update this user's presence state. - * \param userId + * \param userId * The user whose presence state to update. - * \param presence + * \param presence * The new presence state. - * \param statusMsg + * \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 + * \param userId * The user whose presence state to get. */ explicit GetPresenceJob(const QString& userId); @@ -76,30 +76,30 @@ namespace QMatrixClient }; /// Add or remove users from this presence list. - /// + /// /// Adds or removes users from this presence list. class ModifyPresenceListJob : public BaseJob { public: /*! Add or remove users from this presence list. - * \param userId + * \param userId * The user whose presence list is being modified. - * \param invite + * \param invite * A list of user IDs to add to the list. - * \param drop + * \param drop * A list of user IDs to remove from the list. */ explicit ModifyPresenceListJob(const QString& userId, const QStringList& invite = {}, const QStringList& drop = {}); }; /// Get presence events for this presence list. - /// + /// /// Retrieve a list of presence events for every user on this list. class GetPresenceForListJob : public BaseJob { public: /*! Get presence events for this presence list. - * \param userId + * \param userId * The user whose presence list should be retrieved. */ explicit GetPresenceForListJob(const QString& userId); diff --git a/lib/csapi/profile.h b/lib/csapi/profile.h index 694f36b8..23094aff 100644 --- a/lib/csapi/profile.h +++ b/lib/csapi/profile.h @@ -12,23 +12,23 @@ 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 + * \param userId * The user whose display name to set. - * \param displayname + * \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. @@ -36,7 +36,7 @@ namespace QMatrixClient { public: /*! Get the user's display name. - * \param userId + * \param userId * The user whose display name to get. */ explicit GetDisplayNameJob(const QString& userId); @@ -65,23 +65,23 @@ namespace QMatrixClient }; /// 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 + * \param userId * The user whose avatar URL to set. - * \param avatarUrl + * \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. @@ -89,7 +89,7 @@ namespace QMatrixClient { public: /*! Get the user's avatar URL. - * \param userId + * \param userId * The user whose avatar URL to get. */ explicit GetAvatarUrlJob(const QString& userId); @@ -118,7 +118,7 @@ namespace QMatrixClient }; /// 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 @@ -127,7 +127,7 @@ namespace QMatrixClient { public: /*! Get this user's profile information. - * \param userId + * \param userId * The user whose profile information to get. */ explicit GetUserProfileJob(const QString& userId); diff --git a/lib/csapi/pusher.cpp b/lib/csapi/pusher.cpp index 531970b3..d20db88a 100644 --- a/lib/csapi/pusher.cpp +++ b/lib/csapi/pusher.cpp @@ -16,43 +16,41 @@ namespace QMatrixClient { // Converters - template <> struct FromJson<GetPushersJob::PusherData> + template <> struct FromJsonObject<GetPushersJob::PusherData> { - GetPushersJob::PusherData operator()(const QJsonValue& jv) + GetPushersJob::PusherData operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); GetPushersJob::PusherData result; result.url = - fromJson<QString>(_json.value("url"_ls)); + fromJson<QString>(jo.value("url"_ls)); result.format = - fromJson<QString>(_json.value("format"_ls)); + fromJson<QString>(jo.value("format"_ls)); return result; } }; - template <> struct FromJson<GetPushersJob::Pusher> + template <> struct FromJsonObject<GetPushersJob::Pusher> { - GetPushersJob::Pusher operator()(const QJsonValue& jv) + GetPushersJob::Pusher operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); GetPushersJob::Pusher result; result.pushkey = - fromJson<QString>(_json.value("pushkey"_ls)); + fromJson<QString>(jo.value("pushkey"_ls)); result.kind = - fromJson<QString>(_json.value("kind"_ls)); + fromJson<QString>(jo.value("kind"_ls)); result.appId = - fromJson<QString>(_json.value("app_id"_ls)); + fromJson<QString>(jo.value("app_id"_ls)); result.appDisplayName = - fromJson<QString>(_json.value("app_display_name"_ls)); + fromJson<QString>(jo.value("app_display_name"_ls)); result.deviceDisplayName = - fromJson<QString>(_json.value("device_display_name"_ls)); + fromJson<QString>(jo.value("device_display_name"_ls)); result.profileTag = - fromJson<QString>(_json.value("profile_tag"_ls)); + fromJson<QString>(jo.value("profile_tag"_ls)); result.lang = - fromJson<QString>(_json.value("lang"_ls)); + fromJson<QString>(jo.value("lang"_ls)); result.data = - fromJson<GetPushersJob::PusherData>(_json.value("data"_ls)); + fromJson<GetPushersJob::PusherData>(jo.value("data"_ls)); return result; } @@ -100,10 +98,10 @@ namespace QMatrixClient QJsonObject toJson(const PostPusherJob::PusherData& pod) { - QJsonObject _json; - addParam<IfNotEmpty>(_json, QStringLiteral("url"), pod.url); - addParam<IfNotEmpty>(_json, QStringLiteral("format"), pod.format); - return _json; + QJsonObject jo; + addParam<IfNotEmpty>(jo, QStringLiteral("url"), pod.url); + addParam<IfNotEmpty>(jo, QStringLiteral("format"), pod.format); + return jo; } } // namespace QMatrixClient diff --git a/lib/csapi/pusher.h b/lib/csapi/pusher.h index 52717cd1..2b506183 100644 --- a/lib/csapi/pusher.h +++ b/lib/csapi/pusher.h @@ -14,7 +14,7 @@ namespace QMatrixClient // Operations /// Gets the current pushers for the authenticated user - /// + /// /// Gets all currently active pushers for the authenticated user. class GetPushersJob : public BaseJob { @@ -91,7 +91,7 @@ namespace QMatrixClient }; /// 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. @@ -120,7 +120,7 @@ namespace QMatrixClient // Construction/destruction /*! Modify a pusher for this user on the homeserver. - * \param pushkey + * \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 @@ -130,34 +130,34 @@ namespace QMatrixClient * * If the ``kind`` is ``"email"``, this is the email address to * send notifications to. - * \param kind + * \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 + * \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 + * \param appDisplayName * A string that will allow the user to identify what application * owns this pusher. - * \param deviceDisplayName + * \param deviceDisplayName * A string that will allow the user to identify what device owns * this pusher. - * \param lang + * \param lang * The preferred language for receiving notifications (e.g. 'en' * or 'en-US'). - * \param data + * \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 + * \param profileTag * This string determines which set of device specific rules this * pusher executes. - * \param append + * \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 diff --git a/lib/csapi/pushrules.cpp b/lib/csapi/pushrules.cpp index 22976641..ea8ad02a 100644 --- a/lib/csapi/pushrules.cpp +++ b/lib/csapi/pushrules.cpp @@ -80,11 +80,7 @@ const PushRule& GetPushRuleJob::data() const BaseJob::Status GetPushRuleJob::parseJson(const QJsonDocument& data) { - auto json = data.object(); - if (!json.contains("data"_ls)) - return { JsonParseError, - "The key 'data' not found in the response" }; - d->data = fromJson<PushRule>(json.value("data"_ls)); + d->data = fromJson<PushRule>(data); return Success; } diff --git a/lib/csapi/pushrules.h b/lib/csapi/pushrules.h index 1f847013..c038401c 100644 --- a/lib/csapi/pushrules.h +++ b/lib/csapi/pushrules.h @@ -17,7 +17,7 @@ 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 @@ -51,17 +51,17 @@ namespace QMatrixClient }; /// Retrieve a push rule. - /// + /// /// Retrieve a single specified push rule. class GetPushRuleJob : public BaseJob { public: /*! Retrieve a push rule. - * \param scope + * \param scope * ``global`` to specify global rules. - * \param kind + * \param kind * The kind of rule - * \param ruleId + * \param ruleId * The identifier for the rule. */ explicit GetPushRuleJob(const QString& scope, const QString& kind, const QString& ruleId); @@ -90,17 +90,17 @@ namespace QMatrixClient }; /// 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 + * \param scope * ``global`` to specify global rules. - * \param kind + * \param kind * The kind of rule - * \param ruleId + * \param ruleId * The identifier for the rule. */ explicit DeletePushRuleJob(const QString& scope, const QString& kind, const QString& ruleId); @@ -116,53 +116,55 @@ namespace QMatrixClient }; /// 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 + * \param scope * ``global`` to specify global rules. - * \param kind + * \param kind * The kind of rule - * \param ruleId + * \param ruleId * The identifier for the rule. - * \param actions + * \param actions * The action(s) to perform when the conditions for this rule are met. - * \param before + * \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 + * \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 + * \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 + * \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 + * \param scope * Either ``global`` or ``device/<profile_tag>`` to specify global * rules or device rules for the given ``profile_tag``. - * \param kind + * \param kind * The kind of rule - * \param ruleId + * \param ruleId * The identifier for the rule. */ explicit IsPushRuleEnabledJob(const QString& scope, const QString& kind, const QString& ruleId); @@ -191,37 +193,37 @@ namespace QMatrixClient }; /// 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 + * \param scope * ``global`` to specify global rules. - * \param kind + * \param kind * The kind of rule - * \param ruleId + * \param ruleId * The identifier for the rule. - * \param enabled + * \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 + * \param scope * Either ``global`` or ``device/<profile_tag>`` to specify global * rules or device rules for the given ``profile_tag``. - * \param kind + * \param kind * The kind of rule - * \param ruleId + * \param ruleId * The identifier for the rule. */ explicit GetPushRuleActionsJob(const QString& scope, const QString& kind, const QString& ruleId); @@ -250,20 +252,20 @@ namespace QMatrixClient }; /// 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 + * \param scope * ``global`` to specify global rules. - * \param kind + * \param kind * The kind of rule - * \param ruleId + * \param ruleId * The identifier for the rule. - * \param actions + * \param actions * The action(s) to perform for this rule. */ explicit SetPushRuleActionsJob(const QString& scope, const QString& kind, const QString& ruleId, const QStringList& actions); diff --git a/lib/csapi/read_markers.cpp b/lib/csapi/read_markers.cpp new file mode 100644 index 00000000..1bc67ba0 --- /dev/null +++ b/lib/csapi/read_markers.cpp @@ -0,0 +1,26 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + +#include "read_markers.h" + +#include "converters.h" + +#include <QtCore/QStringBuilder> + +using namespace QMatrixClient; + +static const auto basePath = QStringLiteral("/_matrix/client/r0"); + +static const auto SetReadMarkerJobName = QStringLiteral("SetReadMarkerJob"); + +SetReadMarkerJob::SetReadMarkerJob(const QString& roomId, const QString& mFullyRead, const QString& mRead) + : BaseJob(HttpVerb::Post, SetReadMarkerJobName, + basePath % "/rooms/" % roomId % "/read_markers") +{ + QJsonObject _data; + addParam<>(_data, QStringLiteral("m.fully_read"), mFullyRead); + addParam<IfNotEmpty>(_data, QStringLiteral("m.read"), mRead); + setRequestData(_data); +} + diff --git a/lib/csapi/read_markers.h b/lib/csapi/read_markers.h new file mode 100644 index 00000000..f19f46b0 --- /dev/null +++ b/lib/csapi/read_markers.h @@ -0,0 +1,34 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + +#pragma once + +#include "jobs/basejob.h" + + +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:domain.com`` + * 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.h b/lib/csapi/receipts.h index 101f2d05..47e2f3c7 100644 --- a/lib/csapi/receipts.h +++ b/lib/csapi/receipts.h @@ -13,20 +13,20 @@ 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 + * \param roomId * The room in which to send the event. - * \param receiptType + * \param receiptType * The type of receipt to send. - * \param eventId + * \param eventId * The event ID to acknowledge up to. - * \param receipt + * \param receipt * Extra receipt information to attach to ``content`` if any. The * server will automatically set the ``ts`` field. */ diff --git a/lib/csapi/redaction.h b/lib/csapi/redaction.h index 1e01f41b..d02abfd0 100644 --- a/lib/csapi/redaction.h +++ b/lib/csapi/redaction.h @@ -12,7 +12,7 @@ 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. /// @@ -25,14 +25,14 @@ namespace QMatrixClient { public: /*! Strips all non-integrity-critical information out of an event. - * \param roomId + * \param roomId * The room from which to redact the event. - * \param eventId + * \param eventId * The ID of the event to redact - * \param txnId + * \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 + * \param reason * The reason for the event being redacted. */ explicit RedactEventJob(const QString& roomId, const QString& eventId, const QString& txnId, const QString& reason = {}); diff --git a/lib/csapi/registration.cpp b/lib/csapi/registration.cpp index bdfa4606..320ec796 100644 --- a/lib/csapi/registration.cpp +++ b/lib/csapi/registration.cpp @@ -30,7 +30,7 @@ BaseJob::Query queryToRegister(const QString& kind) static const auto RegisterJobName = QStringLiteral("RegisterJob"); -RegisterJob::RegisterJob(const QString& kind, const Omittable<AuthenticationData>& auth, bool bindEmail, const QString& username, const QString& password, const QString& deviceId, const QString& initialDeviceDisplayName) +RegisterJob::RegisterJob(const QString& kind, const Omittable<AuthenticationData>& auth, bool bindEmail, const QString& username, const QString& password, const QString& deviceId, const QString& initialDeviceDisplayName, bool inhibitLogin) : BaseJob(HttpVerb::Post, RegisterJobName, basePath % "/register", queryToRegister(kind), @@ -44,6 +44,7 @@ RegisterJob::RegisterJob(const QString& kind, const Omittable<AuthenticationData addParam<IfNotEmpty>(_data, QStringLiteral("password"), password); addParam<IfNotEmpty>(_data, QStringLiteral("device_id"), deviceId); addParam<IfNotEmpty>(_data, QStringLiteral("initial_device_display_name"), initialDeviceDisplayName); + addParam<IfNotEmpty>(_data, QStringLiteral("inhibit_login"), inhibitLogin); setRequestData(_data); } @@ -72,6 +73,9 @@ const QString& RegisterJob::deviceId() const BaseJob::Status RegisterJob::parseJson(const QJsonDocument& data) { auto json = data.object(); + if (!json.contains("user_id"_ls)) + return { JsonParseError, + "The key 'user_id' not found in the response" }; d->userId = fromJson<QString>(json.value("user_id"_ls)); d->accessToken = fromJson<QString>(json.value("access_token"_ls)); d->homeServer = fromJson<QString>(json.value("home_server"_ls)); @@ -79,35 +83,77 @@ BaseJob::Status RegisterJob::parseJson(const QJsonDocument& data) return Success; } +class RequestTokenToRegisterEmailJob::Private +{ + public: + Sid data; +}; + static const auto RequestTokenToRegisterEmailJobName = QStringLiteral("RequestTokenToRegisterEmailJob"); -RequestTokenToRegisterEmailJob::RequestTokenToRegisterEmailJob(const QString& clientSecret, const QString& email, int sendAttempt, const QString& idServer) +RequestTokenToRegisterEmailJob::RequestTokenToRegisterEmailJob(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) { QJsonObject _data; - addParam<IfNotEmpty>(_data, QStringLiteral("id_server"), idServer); addParam<>(_data, QStringLiteral("client_secret"), clientSecret); addParam<>(_data, QStringLiteral("email"), email); addParam<>(_data, QStringLiteral("send_attempt"), sendAttempt); + addParam<IfNotEmpty>(_data, QStringLiteral("next_link"), nextLink); + addParam<>(_data, QStringLiteral("id_server"), idServer); setRequestData(_data); } +RequestTokenToRegisterEmailJob::~RequestTokenToRegisterEmailJob() = default; + +const Sid& RequestTokenToRegisterEmailJob::data() const +{ + return d->data; +} + +BaseJob::Status RequestTokenToRegisterEmailJob::parseJson(const QJsonDocument& data) +{ + d->data = fromJson<Sid>(data); + return Success; +} + +class RequestTokenToRegisterMSISDNJob::Private +{ + public: + Sid data; +}; + static const auto RequestTokenToRegisterMSISDNJobName = QStringLiteral("RequestTokenToRegisterMSISDNJob"); -RequestTokenToRegisterMSISDNJob::RequestTokenToRegisterMSISDNJob(const QString& clientSecret, const QString& country, const QString& phoneNumber, double sendAttempt, const QString& idServer) +RequestTokenToRegisterMSISDNJob::RequestTokenToRegisterMSISDNJob(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) { QJsonObject _data; - addParam<IfNotEmpty>(_data, QStringLiteral("id_server"), idServer); addParam<>(_data, QStringLiteral("client_secret"), clientSecret); addParam<>(_data, QStringLiteral("country"), country); addParam<>(_data, QStringLiteral("phone_number"), phoneNumber); addParam<>(_data, QStringLiteral("send_attempt"), sendAttempt); + addParam<IfNotEmpty>(_data, QStringLiteral("next_link"), nextLink); + addParam<>(_data, QStringLiteral("id_server"), idServer); setRequestData(_data); } +RequestTokenToRegisterMSISDNJob::~RequestTokenToRegisterMSISDNJob() = default; + +const Sid& RequestTokenToRegisterMSISDNJob::data() const +{ + return d->data; +} + +BaseJob::Status RequestTokenToRegisterMSISDNJob::parseJson(const QJsonDocument& data) +{ + d->data = fromJson<Sid>(data); + return Success; +} + static const auto ChangePasswordJobName = QStringLiteral("ChangePasswordJob"); ChangePasswordJob::ChangePasswordJob(const QString& newPassword, const Omittable<AuthenticationData>& auth) @@ -120,32 +166,75 @@ ChangePasswordJob::ChangePasswordJob(const QString& newPassword, const Omittable setRequestData(_data); } -QUrl RequestTokenToResetPasswordEmailJob::makeRequestUrl(QUrl baseUrl) +class RequestTokenToResetPasswordEmailJob::Private { - return BaseJob::makeRequestUrl(std::move(baseUrl), - basePath % "/account/password/email/requestToken"); -} + public: + Sid data; +}; static const auto RequestTokenToResetPasswordEmailJobName = QStringLiteral("RequestTokenToResetPasswordEmailJob"); -RequestTokenToResetPasswordEmailJob::RequestTokenToResetPasswordEmailJob() +RequestTokenToResetPasswordEmailJob::RequestTokenToResetPasswordEmailJob(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) { + QJsonObject _data; + addParam<>(_data, QStringLiteral("client_secret"), clientSecret); + addParam<>(_data, QStringLiteral("email"), email); + addParam<>(_data, QStringLiteral("send_attempt"), sendAttempt); + addParam<IfNotEmpty>(_data, QStringLiteral("next_link"), nextLink); + addParam<>(_data, QStringLiteral("id_server"), idServer); + setRequestData(_data); } -QUrl RequestTokenToResetPasswordMSISDNJob::makeRequestUrl(QUrl baseUrl) +RequestTokenToResetPasswordEmailJob::~RequestTokenToResetPasswordEmailJob() = default; + +const Sid& RequestTokenToResetPasswordEmailJob::data() const { - return BaseJob::makeRequestUrl(std::move(baseUrl), - basePath % "/account/password/msisdn/requestToken"); + return d->data; } +BaseJob::Status RequestTokenToResetPasswordEmailJob::parseJson(const QJsonDocument& data) +{ + d->data = fromJson<Sid>(data); + return Success; +} + +class RequestTokenToResetPasswordMSISDNJob::Private +{ + public: + Sid data; +}; + static const auto RequestTokenToResetPasswordMSISDNJobName = QStringLiteral("RequestTokenToResetPasswordMSISDNJob"); -RequestTokenToResetPasswordMSISDNJob::RequestTokenToResetPasswordMSISDNJob() +RequestTokenToResetPasswordMSISDNJob::RequestTokenToResetPasswordMSISDNJob(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) { + QJsonObject _data; + addParam<>(_data, QStringLiteral("client_secret"), clientSecret); + addParam<>(_data, QStringLiteral("country"), country); + addParam<>(_data, QStringLiteral("phone_number"), phoneNumber); + addParam<>(_data, QStringLiteral("send_attempt"), sendAttempt); + addParam<IfNotEmpty>(_data, QStringLiteral("next_link"), nextLink); + addParam<>(_data, QStringLiteral("id_server"), idServer); + setRequestData(_data); +} + +RequestTokenToResetPasswordMSISDNJob::~RequestTokenToResetPasswordMSISDNJob() = default; + +const Sid& RequestTokenToResetPasswordMSISDNJob::data() const +{ + return d->data; +} + +BaseJob::Status RequestTokenToResetPasswordMSISDNJob::parseJson(const QJsonDocument& data) +{ + d->data = fromJson<Sid>(data); + return Success; } static const auto DeactivateAccountJobName = QStringLiteral("DeactivateAccountJob"); diff --git a/lib/csapi/registration.h b/lib/csapi/registration.h index cc60b692..9002b5c8 100644 --- a/lib/csapi/registration.h +++ b/lib/csapi/registration.h @@ -6,6 +6,7 @@ #include "jobs/basejob.h" +#include "csapi/../identity/definitions/sid.h" #include "converters.h" #include "csapi/definitions/auth_data.h" @@ -14,7 +15,7 @@ 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. @@ -49,9 +50,9 @@ namespace QMatrixClient { public: /*! Register for an account on this homeserver. - * \param kind + * \param kind * The kind of account to register. Defaults to `user`. - * \param auth + * \param auth * Additional authentication information for the * user-interactive authentication API. Note that this * information is *not* used to define how the registered user @@ -59,23 +60,27 @@ namespace QMatrixClient * 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 + * \param bindEmail * If true, the server binds the email used for authentication to - * the Matrix ID with the ID Server. - * \param username + * 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 + * \param password * The desired password for the account. - * \param deviceId + * \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 + * \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, bool bindEmail = false, const QString& username = {}, const QString& password = {}, const QString& deviceId = {}, const QString& initialDeviceDisplayName = {}); + explicit RegisterJob(const QString& kind = QStringLiteral("user"), const Omittable<AuthenticationData>& auth = none, bool bindEmail = false, const QString& username = {}, const QString& password = {}, const QString& deviceId = {}, const QString& initialDeviceDisplayName = {}, bool inhibitLogin = false); ~RegisterJob() override; // Result properties @@ -87,6 +92,7 @@ namespace QMatrixClient 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. @@ -97,6 +103,7 @@ namespace QMatrixClient 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: @@ -107,55 +114,111 @@ namespace QMatrixClient QScopedPointer<Private> d; }; - /// Requests a validation token be sent to the given email address for the purpose of registering an account - /// - /// Proxies the identity server API ``validate/email/requestToken``, but + /// 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 Home Server. See the Identity Server API for + /// with an account on this homeserver. See the Identity Service API for /// further information. class RequestTokenToRegisterEmailJob : public BaseJob { public: - /*! Requests a validation token be sent to the given email address for the purpose of registering an account - * \param clientSecret - * Client-generated secret string used to protect this session - * \param email - * The email address - * \param sendAttempt - * Used to distinguish protocol level retries from requests to re-send the email. - * \param idServer - * The ID server to send the onward request to as a hostname with an appended colon and port number if the port is not the default. + /*! 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 = {}); + 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 server API ``validate/msisdn/requestToken``, but + /// + /// 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 Home Server. See the Identity Server API for + /// 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 - * Client-generated secret string used to protect this session. - * \param country + * \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. - * \param sendAttempt - * Used to distinguish protocol level retries from requests to re-send the SMS message. - * \param idServer - * The ID server to send the onward request to as a hostname with an appended colon and port number if the port is not the default. + * \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, double sendAttempt, const QString& idServer = {}); + 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`_. @@ -169,19 +232,19 @@ namespace QMatrixClient { public: /*! Changes a user's password. - * \param newPassword + * \param newPassword * The new password for the account. - * \param auth + * \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 server API ``validate/email/requestToken``, but + /// + /// Proxies the Identity Service API ``validate/email/requestToken``, but /// first checks that the given email address **is** associated with an account - /// on this Home Server. This API should be used to request + /// 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 @@ -196,28 +259,55 @@ namespace QMatrixClient class RequestTokenToResetPasswordEmailJob : public BaseJob { public: - explicit RequestTokenToResetPasswordEmailJob(); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * RequestTokenToResetPasswordEmailJob is necessary but the job - * itself isn't. + /*! 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. */ - static QUrl makeRequestUrl(QUrl baseUrl); + 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 server API ``validate/msisdn/requestToken``, but + /// + /// Proxies the Identity Service API ``validate/msisdn/requestToken``, but /// first checks that the given phone number **is** associated with an account - /// on this Home Server. This API should be used to request + /// 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 email address could be found. The server may instead send an + /// 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. /// @@ -227,20 +317,50 @@ namespace QMatrixClient class RequestTokenToResetPasswordMSISDNJob : public BaseJob { public: - explicit RequestTokenToResetPasswordMSISDNJob(); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * RequestTokenToResetPasswordMSISDNJob is necessary but the job - * itself isn't. + /*! 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. */ - static QUrl makeRequestUrl(QUrl baseUrl); + 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. /// @@ -255,14 +375,14 @@ namespace QMatrixClient { public: /*! Deactivate a user's account. - * \param auth + * \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 @@ -279,7 +399,7 @@ namespace QMatrixClient { public: /*! Checks to see if a username is available on the server. - * \param username + * \param username * The username to check the availability of. */ explicit CheckUsernameAvailabilityJob(const QString& username); diff --git a/lib/csapi/report_content.h b/lib/csapi/report_content.h index aa5f8a6b..a20c6838 100644 --- a/lib/csapi/report_content.h +++ b/lib/csapi/report_content.h @@ -13,21 +13,21 @@ namespace QMatrixClient // 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 + * \param roomId * The room in which the event being reported is located. - * \param eventId + * \param eventId * The event to report. - * \param score + * \param score * The score to rate this content as where -100 is most offensive * and 0 is inoffensive. - * \param reason + * \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); diff --git a/lib/csapi/room_send.h b/lib/csapi/room_send.h index 915a8f78..85c298e0 100644 --- a/lib/csapi/room_send.h +++ b/lib/csapi/room_send.h @@ -13,7 +13,7 @@ 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. @@ -25,15 +25,15 @@ namespace QMatrixClient { public: /*! Send a message event to the given room. - * \param roomId + * \param roomId * The room to send the event to. - * \param eventType + * \param eventType * The type of event to send. - * \param txnId + * \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 + * \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. diff --git a/lib/csapi/room_state.h b/lib/csapi/room_state.h index 77ddf3e6..67420545 100644 --- a/lib/csapi/room_state.h +++ b/lib/csapi/room_state.h @@ -13,7 +13,7 @@ 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. @@ -29,13 +29,13 @@ namespace QMatrixClient { public: /*! Send a state event to the given room. - * \param roomId + * \param roomId * The room to set the state in - * \param eventType + * \param eventType * The type of event to send. - * \param stateKey + * \param stateKey * The state_key for the state to send. Defaults to the empty string. - * \param body + * \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. @@ -65,7 +65,7 @@ namespace QMatrixClient }; /// 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 @@ -82,11 +82,11 @@ namespace QMatrixClient { public: /*! Send a state event to the given room. - * \param roomId + * \param roomId * The room to set the state in - * \param eventType + * \param eventType * The type of event to send. - * \param body + * \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 diff --git a/lib/csapi/rooms.cpp b/lib/csapi/rooms.cpp index a70d9543..3befeee5 100644 --- a/lib/csapi/rooms.cpp +++ b/lib/csapi/rooms.cpp @@ -42,11 +42,7 @@ EventPtr&& GetOneRoomEventJob::data() BaseJob::Status GetOneRoomEventJob::parseJson(const QJsonDocument& data) { - auto json = data.object(); - if (!json.contains("data"_ls)) - return { JsonParseError, - "The key 'data' not found in the response" }; - d->data = fromJson<EventPtr>(json.value("data"_ls)); + d->data = fromJson<EventPtr>(data); return Success; } @@ -80,11 +76,7 @@ StateEventPtr&& GetRoomStateWithKeyJob::data() BaseJob::Status GetRoomStateWithKeyJob::parseJson(const QJsonDocument& data) { - auto json = data.object(); - if (!json.contains("data"_ls)) - return { JsonParseError, - "The key 'data' not found in the response" }; - d->data = fromJson<StateEventPtr>(json.value("data"_ls)); + d->data = fromJson<StateEventPtr>(data); return Success; } @@ -118,11 +110,7 @@ StateEventPtr&& GetRoomStateByTypeJob::data() BaseJob::Status GetRoomStateByTypeJob::parseJson(const QJsonDocument& data) { - auto json = data.object(); - if (!json.contains("data"_ls)) - return { JsonParseError, - "The key 'data' not found in the response" }; - d->data = fromJson<StateEventPtr>(json.value("data"_ls)); + d->data = fromJson<StateEventPtr>(data); return Success; } @@ -156,11 +144,7 @@ StateEvents&& GetRoomStateJob::data() BaseJob::Status GetRoomStateJob::parseJson(const QJsonDocument& data) { - auto json = data.object(); - if (!json.contains("data"_ls)) - return { JsonParseError, - "The key 'data' not found in the response" }; - d->data = fromJson<StateEvents>(json.value("data"_ls)); + d->data = fromJson<StateEvents>(data); return Success; } @@ -203,16 +187,15 @@ namespace QMatrixClient { // Converters - template <> struct FromJson<GetJoinedMembersByRoomJob::RoomMember> + template <> struct FromJsonObject<GetJoinedMembersByRoomJob::RoomMember> { - GetJoinedMembersByRoomJob::RoomMember operator()(const QJsonValue& jv) + GetJoinedMembersByRoomJob::RoomMember operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); GetJoinedMembersByRoomJob::RoomMember result; result.displayName = - fromJson<QString>(_json.value("display_name"_ls)); + fromJson<QString>(jo.value("display_name"_ls)); result.avatarUrl = - fromJson<QString>(_json.value("avatar_url"_ls)); + fromJson<QString>(jo.value("avatar_url"_ls)); return result; } diff --git a/lib/csapi/rooms.h b/lib/csapi/rooms.h index 8d508e94..2366918b 100644 --- a/lib/csapi/rooms.h +++ b/lib/csapi/rooms.h @@ -16,16 +16,16 @@ namespace QMatrixClient // Operations /// 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 + * \param roomId * The ID of the room the event is in. - * \param eventId + * \param eventId * The event ID to get. */ explicit GetOneRoomEventJob(const QString& roomId, const QString& eventId); @@ -54,7 +54,7 @@ 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 @@ -63,11 +63,11 @@ namespace QMatrixClient { public: /*! Get the state identified by the type and key. - * \param roomId + * \param roomId * The room to look up the state in. - * \param eventType + * \param eventType * The type of state to look up. - * \param stateKey + * \param stateKey * The key of the state to look up. */ explicit GetRoomStateWithKeyJob(const QString& roomId, const QString& eventType, const QString& stateKey); @@ -96,7 +96,7 @@ namespace QMatrixClient }; /// 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 @@ -107,9 +107,9 @@ namespace QMatrixClient { public: /*! Get the state identified by the type, with the empty state key. - * \param roomId + * \param roomId * The room to look up the state in. - * \param eventType + * \param eventType * The type of state to look up. */ explicit GetRoomStateByTypeJob(const QString& roomId, const QString& eventType); @@ -138,13 +138,13 @@ namespace QMatrixClient }; /// 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 + * \param roomId * The room to look up the state for. */ explicit GetRoomStateJob(const QString& roomId); @@ -176,13 +176,13 @@ namespace QMatrixClient }; /// 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 + * \param roomId * The room to get the member events for. */ explicit GetMembersByRoomJob(const QString& roomId); @@ -211,7 +211,7 @@ namespace QMatrixClient }; /// 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 { @@ -230,7 +230,7 @@ namespace QMatrixClient // Construction/destruction /*! Gets the list of currently joined users and their profile data. - * \param roomId + * \param roomId * The room to get the members of. */ explicit GetJoinedMembersByRoomJob(const QString& roomId); diff --git a/lib/csapi/search.cpp b/lib/csapi/search.cpp index b2e58931..9436eb47 100644 --- a/lib/csapi/search.cpp +++ b/lib/csapi/search.cpp @@ -18,148 +18,142 @@ namespace QMatrixClient QJsonObject toJson(const SearchJob::IncludeEventContext& pod) { - QJsonObject _json; - addParam<IfNotEmpty>(_json, QStringLiteral("before_limit"), pod.beforeLimit); - addParam<IfNotEmpty>(_json, QStringLiteral("after_limit"), pod.afterLimit); - addParam<IfNotEmpty>(_json, QStringLiteral("include_profile"), pod.includeProfile); - return _json; + QJsonObject jo; + addParam<IfNotEmpty>(jo, QStringLiteral("before_limit"), pod.beforeLimit); + addParam<IfNotEmpty>(jo, QStringLiteral("after_limit"), pod.afterLimit); + addParam<IfNotEmpty>(jo, QStringLiteral("include_profile"), pod.includeProfile); + return jo; } QJsonObject toJson(const SearchJob::Group& pod) { - QJsonObject _json; - addParam<IfNotEmpty>(_json, QStringLiteral("key"), pod.key); - return _json; + QJsonObject jo; + addParam<IfNotEmpty>(jo, QStringLiteral("key"), pod.key); + return jo; } QJsonObject toJson(const SearchJob::Groupings& pod) { - QJsonObject _json; - addParam<IfNotEmpty>(_json, QStringLiteral("group_by"), pod.groupBy); - return _json; + QJsonObject jo; + addParam<IfNotEmpty>(jo, QStringLiteral("group_by"), pod.groupBy); + return jo; } QJsonObject toJson(const SearchJob::RoomEventsCriteria& pod) { - QJsonObject _json; - addParam<>(_json, QStringLiteral("search_term"), pod.searchTerm); - addParam<IfNotEmpty>(_json, QStringLiteral("keys"), pod.keys); - addParam<IfNotEmpty>(_json, QStringLiteral("filter"), pod.filter); - addParam<IfNotEmpty>(_json, QStringLiteral("order_by"), pod.orderBy); - addParam<IfNotEmpty>(_json, QStringLiteral("event_context"), pod.eventContext); - addParam<IfNotEmpty>(_json, QStringLiteral("include_state"), pod.includeState); - addParam<IfNotEmpty>(_json, QStringLiteral("groupings"), pod.groupings); - return _json; + QJsonObject jo; + 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); + return jo; } QJsonObject toJson(const SearchJob::Categories& pod) { - QJsonObject _json; - addParam<IfNotEmpty>(_json, QStringLiteral("room_events"), pod.roomEvents); - return _json; + QJsonObject jo; + addParam<IfNotEmpty>(jo, QStringLiteral("room_events"), pod.roomEvents); + return jo; } - template <> struct FromJson<SearchJob::UserProfile> + template <> struct FromJsonObject<SearchJob::UserProfile> { - SearchJob::UserProfile operator()(const QJsonValue& jv) + SearchJob::UserProfile operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); SearchJob::UserProfile result; result.displayname = - fromJson<QString>(_json.value("displayname"_ls)); + fromJson<QString>(jo.value("displayname"_ls)); result.avatarUrl = - fromJson<QString>(_json.value("avatar_url"_ls)); + fromJson<QString>(jo.value("avatar_url"_ls)); return result; } }; - template <> struct FromJson<SearchJob::EventContext> + template <> struct FromJsonObject<SearchJob::EventContext> { - SearchJob::EventContext operator()(const QJsonValue& jv) + SearchJob::EventContext operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); SearchJob::EventContext result; result.begin = - fromJson<QString>(_json.value("start"_ls)); + fromJson<QString>(jo.value("start"_ls)); result.end = - fromJson<QString>(_json.value("end"_ls)); + fromJson<QString>(jo.value("end"_ls)); result.profileInfo = - fromJson<QHash<QString, SearchJob::UserProfile>>(_json.value("profile_info"_ls)); + fromJson<QHash<QString, SearchJob::UserProfile>>(jo.value("profile_info"_ls)); result.eventsBefore = - fromJson<RoomEvents>(_json.value("events_before"_ls)); + fromJson<RoomEvents>(jo.value("events_before"_ls)); result.eventsAfter = - fromJson<RoomEvents>(_json.value("events_after"_ls)); + fromJson<RoomEvents>(jo.value("events_after"_ls)); return result; } }; - template <> struct FromJson<SearchJob::Result> + template <> struct FromJsonObject<SearchJob::Result> { - SearchJob::Result operator()(const QJsonValue& jv) + SearchJob::Result operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); SearchJob::Result result; result.rank = - fromJson<double>(_json.value("rank"_ls)); + fromJson<double>(jo.value("rank"_ls)); result.result = - fromJson<RoomEventPtr>(_json.value("result"_ls)); + fromJson<RoomEventPtr>(jo.value("result"_ls)); result.context = - fromJson<SearchJob::EventContext>(_json.value("context"_ls)); + fromJson<SearchJob::EventContext>(jo.value("context"_ls)); return result; } }; - template <> struct FromJson<SearchJob::GroupValue> + template <> struct FromJsonObject<SearchJob::GroupValue> { - SearchJob::GroupValue operator()(const QJsonValue& jv) + SearchJob::GroupValue operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); SearchJob::GroupValue result; result.nextBatch = - fromJson<QString>(_json.value("next_batch"_ls)); + fromJson<QString>(jo.value("next_batch"_ls)); result.order = - fromJson<int>(_json.value("order"_ls)); + fromJson<int>(jo.value("order"_ls)); result.results = - fromJson<QStringList>(_json.value("results"_ls)); + fromJson<QStringList>(jo.value("results"_ls)); return result; } }; - template <> struct FromJson<SearchJob::ResultRoomEvents> + template <> struct FromJsonObject<SearchJob::ResultRoomEvents> { - SearchJob::ResultRoomEvents operator()(const QJsonValue& jv) + SearchJob::ResultRoomEvents operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); SearchJob::ResultRoomEvents result; result.count = - fromJson<qint64>(_json.value("count"_ls)); + fromJson<int>(jo.value("count"_ls)); result.highlights = - fromJson<QStringList>(_json.value("highlights"_ls)); + fromJson<QStringList>(jo.value("highlights"_ls)); result.results = - fromJson<std::vector<SearchJob::Result>>(_json.value("results"_ls)); + fromJson<std::vector<SearchJob::Result>>(jo.value("results"_ls)); result.state = - fromJson<std::unordered_map<QString, StateEvents>>(_json.value("state"_ls)); + fromJson<std::unordered_map<QString, StateEvents>>(jo.value("state"_ls)); result.groups = - fromJson<QHash<QString, QHash<QString, SearchJob::GroupValue>>>(_json.value("groups"_ls)); + fromJson<QHash<QString, QHash<QString, SearchJob::GroupValue>>>(jo.value("groups"_ls)); result.nextBatch = - fromJson<QString>(_json.value("next_batch"_ls)); + fromJson<QString>(jo.value("next_batch"_ls)); return result; } }; - template <> struct FromJson<SearchJob::ResultCategories> + template <> struct FromJsonObject<SearchJob::ResultCategories> { - SearchJob::ResultCategories operator()(const QJsonValue& jv) + SearchJob::ResultCategories operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); SearchJob::ResultCategories result; result.roomEvents = - fromJson<SearchJob::ResultRoomEvents>(_json.value("room_events"_ls)); + fromJson<SearchJob::ResultRoomEvents>(jo.value("room_events"_ls)); return result; } diff --git a/lib/csapi/search.h b/lib/csapi/search.h index 6cb0ac19..85b0886b 100644 --- a/lib/csapi/search.h +++ b/lib/csapi/search.h @@ -6,19 +6,19 @@ #include "jobs/basejob.h" -#include <QtCore/QJsonObject> +#include "csapi/definitions/room_event_filter.h" #include "converters.h" #include <QtCore/QVector> +#include "events/eventloader.h" #include <unordered_map> #include <QtCore/QHash> -#include "events/eventloader.h" namespace QMatrixClient { // Operations /// Perform a server-side search. - /// + /// /// Performs a full text search across different categories. class SearchJob : public BaseJob { @@ -65,7 +65,7 @@ namespace QMatrixClient /// The keys to search. Defaults to all. QStringList keys; /// This takes a `filter`_. - QJsonObject filter; + Omittable<RoomEventFilter> filter; /// The order in which to search for results. /// By default, this is ``"rank"``. QString orderBy; @@ -146,7 +146,7 @@ namespace QMatrixClient struct ResultRoomEvents { /// An approximate count of the total number of results found. - Omittable<qint64> count; + 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. @@ -181,11 +181,11 @@ namespace QMatrixClient // Construction/destruction /*! Perform a server-side search. - * \param searchCategories + * \param searchCategories * Describes which categories to search in and their criteria. - * \param nextBatch + * \param nextBatch * The point to return events from. If given, this should be a - * `next_batch` result from a previous call to this endpoint. + * ``next_batch`` result from a previous call to this endpoint. */ explicit SearchJob(const Categories& searchCategories, const QString& nextBatch = {}); ~SearchJob() override; diff --git a/lib/csapi/tags.cpp b/lib/csapi/tags.cpp index 1afc3bfc..808915ac 100644 --- a/lib/csapi/tags.cpp +++ b/lib/csapi/tags.cpp @@ -12,10 +12,28 @@ using namespace QMatrixClient; static const auto basePath = QStringLiteral("/_matrix/client/r0"); +namespace QMatrixClient +{ + // Converters + + template <> struct FromJsonObject<GetRoomTagsJob::Tag> + { + GetRoomTagsJob::Tag operator()(QJsonObject jo) const + { + GetRoomTagsJob::Tag result; + result.order = + fromJson<float>(jo.take("order"_ls)); + + result.additionalProperties = fromJson<QVariantHash>(jo); + return result; + } + }; +} // namespace QMatrixClient + class GetRoomTagsJob::Private { public: - QJsonObject tags; + QHash<QString, Tag> tags; }; QUrl GetRoomTagsJob::makeRequestUrl(QUrl baseUrl, const QString& userId, const QString& roomId) @@ -35,7 +53,7 @@ GetRoomTagsJob::GetRoomTagsJob(const QString& userId, const QString& roomId) GetRoomTagsJob::~GetRoomTagsJob() = default; -const QJsonObject& GetRoomTagsJob::tags() const +const QHash<QString, GetRoomTagsJob::Tag>& GetRoomTagsJob::tags() const { return d->tags; } @@ -43,17 +61,19 @@ const QJsonObject& GetRoomTagsJob::tags() const BaseJob::Status GetRoomTagsJob::parseJson(const QJsonDocument& data) { auto json = data.object(); - d->tags = fromJson<QJsonObject>(json.value("tags"_ls)); + d->tags = fromJson<QHash<QString, Tag>>(json.value("tags"_ls)); return Success; } static const auto SetRoomTagJobName = QStringLiteral("SetRoomTagJob"); -SetRoomTagJob::SetRoomTagJob(const QString& userId, const QString& roomId, const QString& tag, const QJsonObject& body) +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) { - setRequestData(Data(toJson(body))); + QJsonObject _data; + addParam<IfNotEmpty>(_data, QStringLiteral("order"), order); + setRequestData(_data); } QUrl DeleteRoomTagJob::makeRequestUrl(QUrl baseUrl, const QString& userId, const QString& roomId, const QString& tag) diff --git a/lib/csapi/tags.h b/lib/csapi/tags.h index e8664390..2c20c2a2 100644 --- a/lib/csapi/tags.h +++ b/lib/csapi/tags.h @@ -6,24 +6,40 @@ #include "jobs/basejob.h" -#include <QtCore/QJsonObject> +#include <QtCore/QVariant> +#include <QtCore/QHash> +#include "converters.h" 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 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 + * \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. + * 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); @@ -40,7 +56,7 @@ namespace QMatrixClient // Result properties /// List the tags set by a user on a room. - const QJsonObject& tags() const; + const QHash<QString, Tag>& tags() const; protected: Status parseJson(const QJsonDocument& data) override; @@ -51,38 +67,39 @@ namespace QMatrixClient }; /// 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 + * \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 + * 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 body - * Extra data for the tag, e.g. ordering. + * \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, const QJsonObject& body = {}); + 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 + * \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 + * 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); diff --git a/lib/csapi/third_party_lookup.cpp b/lib/csapi/third_party_lookup.cpp index 406e6d34..3ba1a5ad 100644 --- a/lib/csapi/third_party_lookup.cpp +++ b/lib/csapi/third_party_lookup.cpp @@ -42,11 +42,7 @@ const QHash<QString, ThirdPartyProtocol>& GetProtocolsJob::data() const BaseJob::Status GetProtocolsJob::parseJson(const QJsonDocument& data) { - auto json = data.object(); - if (!json.contains("data"_ls)) - return { JsonParseError, - "The key 'data' not found in the response" }; - d->data = fromJson<QHash<QString, ThirdPartyProtocol>>(json.value("data"_ls)); + d->data = fromJson<QHash<QString, ThirdPartyProtocol>>(data); return Success; } @@ -80,11 +76,7 @@ const ThirdPartyProtocol& GetProtocolMetadataJob::data() const BaseJob::Status GetProtocolMetadataJob::parseJson(const QJsonDocument& data) { - auto json = data.object(); - if (!json.contains("data"_ls)) - return { JsonParseError, - "The key 'data' not found in the response" }; - d->data = fromJson<ThirdPartyProtocol>(json.value("data"_ls)); + d->data = fromJson<ThirdPartyProtocol>(data); return Success; } @@ -127,11 +119,7 @@ const QVector<ThirdPartyLocation>& QueryLocationByProtocolJob::data() const BaseJob::Status QueryLocationByProtocolJob::parseJson(const QJsonDocument& data) { - auto json = data.object(); - if (!json.contains("data"_ls)) - return { JsonParseError, - "The key 'data' not found in the response" }; - d->data = fromJson<QVector<ThirdPartyLocation>>(json.value("data"_ls)); + d->data = fromJson<QVector<ThirdPartyLocation>>(data); return Success; } @@ -174,11 +162,7 @@ const QVector<ThirdPartyUser>& QueryUserByProtocolJob::data() const BaseJob::Status QueryUserByProtocolJob::parseJson(const QJsonDocument& data) { - auto json = data.object(); - if (!json.contains("data"_ls)) - return { JsonParseError, - "The key 'data' not found in the response" }; - d->data = fromJson<QVector<ThirdPartyUser>>(json.value("data"_ls)); + d->data = fromJson<QVector<ThirdPartyUser>>(data); return Success; } @@ -221,11 +205,7 @@ const QVector<ThirdPartyLocation>& QueryLocationByAliasJob::data() const BaseJob::Status QueryLocationByAliasJob::parseJson(const QJsonDocument& data) { - auto json = data.object(); - if (!json.contains("data"_ls)) - return { JsonParseError, - "The key 'data' not found in the response" }; - d->data = fromJson<QVector<ThirdPartyLocation>>(json.value("data"_ls)); + d->data = fromJson<QVector<ThirdPartyLocation>>(data); return Success; } @@ -268,11 +248,7 @@ const QVector<ThirdPartyUser>& QueryUserByIDJob::data() const BaseJob::Status QueryUserByIDJob::parseJson(const QJsonDocument& data) { - auto json = data.object(); - if (!json.contains("data"_ls)) - return { JsonParseError, - "The key 'data' not found in the response" }; - d->data = fromJson<QVector<ThirdPartyUser>>(json.value("data"_ls)); + d->data = fromJson<QVector<ThirdPartyUser>>(data); return Success; } diff --git a/lib/csapi/third_party_lookup.h b/lib/csapi/third_party_lookup.h index 03d607a8..3a60432b 100644 --- a/lib/csapi/third_party_lookup.h +++ b/lib/csapi/third_party_lookup.h @@ -18,7 +18,7 @@ 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. @@ -51,13 +51,13 @@ namespace QMatrixClient }; /// 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 + * \param protocol * The name of the protocol. */ explicit GetProtocolMetadataJob(const QString& protocol); @@ -85,8 +85,8 @@ namespace QMatrixClient QScopedPointer<Private> d; }; - /// Retreive Matrix-side portals rooms leading to a third party location. - /// + /// 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 @@ -98,10 +98,10 @@ namespace QMatrixClient class QueryLocationByProtocolJob : public BaseJob { public: - /*! Retreive Matrix-side portals rooms leading to a third party location. - * \param protocol + /*! 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 + * \param searchFields * One or more custom fields to help identify the third party * location. */ @@ -131,16 +131,16 @@ namespace QMatrixClient }; /// 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 + * \param protocol * The name of the protocol. - * \param fields + * \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 = {}); @@ -169,14 +169,14 @@ namespace QMatrixClient }; /// Reverse-lookup third party locations given a Matrix room alias. - /// - /// Retreive an array of third party network locations from a Matrix room + /// + /// 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 + * \param alias * The Matrix room alias to look up. */ explicit QueryLocationByAliasJob(const QString& alias); @@ -205,13 +205,13 @@ namespace QMatrixClient }; /// Reverse-lookup third party users given a Matrix User ID. - /// - /// Retreive an array of third party users from 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 + * \param userid * The Matrix User ID to look up. */ explicit QueryUserByIDJob(const QString& userid); diff --git a/lib/csapi/third_party_membership.h b/lib/csapi/third_party_membership.h index e8276b3c..d18fe554 100644 --- a/lib/csapi/third_party_membership.h +++ b/lib/csapi/third_party_membership.h @@ -12,7 +12,7 @@ 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. @@ -61,13 +61,13 @@ namespace QMatrixClient { public: /*! Invite a user to participate in a particular room. - * \param roomId + * \param roomId * The room identifier (not alias) to which to invite the user. - * \param idServer + * \param idServer * The hostname+port of the identity server which should be used for third party identifier lookups. - * \param medium + * \param medium * The kind of address being passed in the address field, for example ``email``. - * \param address + * \param address * The invitee's third party identifier. */ explicit InviteBy3PIDJob(const QString& roomId, const QString& idServer, const QString& medium, const QString& address); diff --git a/lib/csapi/to_device.h b/lib/csapi/to_device.h index 6aff3ae5..10f6b971 100644 --- a/lib/csapi/to_device.h +++ b/lib/csapi/to_device.h @@ -14,20 +14,20 @@ 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 + * \param eventType * The type of event to send. - * \param txnId + * \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 + * \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. diff --git a/lib/csapi/typing.h b/lib/csapi/typing.h index aec489c2..c6201440 100644 --- a/lib/csapi/typing.h +++ b/lib/csapi/typing.h @@ -13,7 +13,7 @@ namespace QMatrixClient // 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 @@ -22,14 +22,14 @@ namespace QMatrixClient { public: /*! Informs the server that the user has started or stopped typing. - * \param userId + * \param userId * The user who has started to type. - * \param roomId + * \param roomId * The room in which the user is typing. - * \param typing + * \param typing * Whether the user is typing or not. If ``false``, the ``timeout`` * key can be omitted. - * \param timeout + * \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); diff --git a/lib/csapi/users.cpp b/lib/csapi/users.cpp index 408a8cad..deb9cb8a 100644 --- a/lib/csapi/users.cpp +++ b/lib/csapi/users.cpp @@ -16,18 +16,17 @@ namespace QMatrixClient { // Converters - template <> struct FromJson<SearchUserDirectoryJob::User> + template <> struct FromJsonObject<SearchUserDirectoryJob::User> { - SearchUserDirectoryJob::User operator()(const QJsonValue& jv) + SearchUserDirectoryJob::User operator()(const QJsonObject& jo) const { - const auto& _json = jv.toObject(); SearchUserDirectoryJob::User result; result.userId = - fromJson<QString>(_json.value("user_id"_ls)); + fromJson<QString>(jo.value("user_id"_ls)); result.displayName = - fromJson<QString>(_json.value("display_name"_ls)); + fromJson<QString>(jo.value("display_name"_ls)); result.avatarUrl = - fromJson<QString>(_json.value("avatar_url"_ls)); + fromJson<QString>(jo.value("avatar_url"_ls)); return result; } diff --git a/lib/csapi/users.h b/lib/csapi/users.h index 3ff10db6..1e355b8f 100644 --- a/lib/csapi/users.h +++ b/lib/csapi/users.h @@ -14,16 +14,32 @@ 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. /// - /// This API performs a server-side search over all users registered on the server. - /// It searches user ID and displayname case-insensitively for users that you share a room with or that are in public rooms. + /// 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 - /// This API performs a server-side search over all users registered on the server. - /// It searches user ID and displayname case-insensitively for users that you share a room with or that are in public rooms. + /// 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. @@ -37,10 +53,10 @@ namespace QMatrixClient // Construction/destruction /*! Searches the user directory. - * \param searchTerm + * \param searchTerm * The term to search for - * \param limit - * The maximum number of results to return (Defaults to 10). + * \param limit + * The maximum number of results to return. Defaults to 10. */ explicit SearchUserDirectoryJob(const QString& searchTerm, Omittable<int> limit = none); ~SearchUserDirectoryJob() override; diff --git a/lib/csapi/versions.h b/lib/csapi/versions.h index 3303752d..309de184 100644 --- a/lib/csapi/versions.h +++ b/lib/csapi/versions.h @@ -12,7 +12,7 @@ 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``. diff --git a/lib/csapi/voip.cpp b/lib/csapi/voip.cpp index 8ecf92c6..0479b645 100644 --- a/lib/csapi/voip.cpp +++ b/lib/csapi/voip.cpp @@ -42,11 +42,7 @@ const QJsonObject& GetTurnServerJob::data() const BaseJob::Status GetTurnServerJob::parseJson(const QJsonDocument& data) { - auto json = data.object(); - if (!json.contains("data"_ls)) - return { JsonParseError, - "The key 'data' not found in the response" }; - d->data = fromJson<QJsonObject>(json.value("data"_ls)); + d->data = fromJson<QJsonObject>(data); return Success; } diff --git a/lib/csapi/voip.h b/lib/csapi/voip.h index ca190df7..bb858499 100644 --- a/lib/csapi/voip.h +++ b/lib/csapi/voip.h @@ -13,7 +13,7 @@ namespace QMatrixClient // Operations /// Obtain TURN server credentials. - /// + /// /// This API provides credentials for the client to use when initiating /// calls. class GetTurnServerJob : public BaseJob diff --git a/lib/csapi/wellknown.cpp b/lib/csapi/wellknown.cpp new file mode 100644 index 00000000..d42534a0 --- /dev/null +++ b/lib/csapi/wellknown.cpp @@ -0,0 +1,59 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + +#include "wellknown.h" + +#include "converters.h" + +#include <QtCore/QStringBuilder> + +using namespace QMatrixClient; + +static const auto basePath = QStringLiteral("/.well-known"); + +class GetWellknownJob::Private +{ + public: + HomeserverInformation homeserver; + Omittable<IdentityServerInformation> identityServer; +}; + +QUrl GetWellknownJob::makeRequestUrl(QUrl baseUrl) +{ + return BaseJob::makeRequestUrl(std::move(baseUrl), + basePath % "/matrix/client"); +} + +static const auto GetWellknownJobName = QStringLiteral("GetWellknownJob"); + +GetWellknownJob::GetWellknownJob() + : BaseJob(HttpVerb::Get, GetWellknownJobName, + basePath % "/matrix/client", false) + , d(new Private) +{ +} + +GetWellknownJob::~GetWellknownJob() = default; + +const HomeserverInformation& GetWellknownJob::homeserver() const +{ + return d->homeserver; +} + +const Omittable<IdentityServerInformation>& GetWellknownJob::identityServer() const +{ + return d->identityServer; +} + +BaseJob::Status GetWellknownJob::parseJson(const QJsonDocument& data) +{ + auto json = data.object(); + if (!json.contains("m.homeserver"_ls)) + return { JsonParseError, + "The key 'm.homeserver' not found in the response" }; + d->homeserver = fromJson<HomeserverInformation>(json.value("m.homeserver"_ls)); + d->identityServer = fromJson<IdentityServerInformation>(json.value("m.identity_server"_ls)); + return Success; +} + diff --git a/lib/csapi/wellknown.h b/lib/csapi/wellknown.h new file mode 100644 index 00000000..df4c8c6e --- /dev/null +++ b/lib/csapi/wellknown.h @@ -0,0 +1,56 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + +#pragma once + +#include "jobs/basejob.h" + +#include "converters.h" +#include "csapi/definitions/wellknown/identity_server.h" +#include "csapi/definitions/wellknown/homeserver.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 + + /// Information about the homeserver to connect to. + const HomeserverInformation& homeserver() const; + /// Optional. Information about the identity server to connect to. + const Omittable<IdentityServerInformation>& identityServer() const; + + protected: + Status parseJson(const QJsonDocument& data) override; + + private: + class Private; + QScopedPointer<Private> d; + }; +} // namespace QMatrixClient diff --git a/lib/csapi/whoami.h b/lib/csapi/whoami.h index 1ada7406..71e9d532 100644 --- a/lib/csapi/whoami.h +++ b/lib/csapi/whoami.h @@ -12,7 +12,7 @@ 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, diff --git a/lib/csapi/{{base}}.cpp.mustache b/lib/csapi/{{base}}.cpp.mustache index eced328c..64fd8bf3 100644 --- a/lib/csapi/{{base}}.cpp.mustache +++ b/lib/csapi/{{base}}.cpp.mustache @@ -10,19 +10,18 @@ using namespace QMatrixClient; {{#models.model}}{{#in?}} QJsonObject QMatrixClient::toJson(const {{qualifiedName}}& pod) { - QJsonObject _json{{#propertyMap}} = toJson(pod.{{nameCamelCase}}){{/propertyMap}};{{#vars}} - addParam<{{^required?}}IfNotEmpty{{/required?}}>(_json, QStringLiteral("{{baseName}}"), pod.{{nameCamelCase}});{{/vars}} - return _json; + QJsonObject jo{{#propertyMap}} = toJson(pod.{{nameCamelCase}}){{/propertyMap}};{{#vars}} + addParam<{{^required?}}IfNotEmpty{{/required?}}>(jo, QStringLiteral("{{baseName}}"), pod.{{nameCamelCase}});{{/vars}} + return jo; } {{/in?}}{{#out?}} -{{qualifiedName}} FromJson<{{qualifiedName}}>::operator()(const QJsonValue& jv) +{{qualifiedName}} FromJsonObject<{{qualifiedName}}>::operator()({{^propertyMap}}const QJsonObject&{{/propertyMap}}{{#propertyMap}}QJsonObject{{/propertyMap}} jo) const { - {{^propertyMap}}const auto&{{/propertyMap}}{{#propertyMap}}auto{{/propertyMap}} _json = jv.toObject(); {{qualifiedName}} result; - {{#vars}}result.{{nameCamelCase}} = - fromJson<{{dataType.name}}>(_json.{{#propertyMap}}take{{/propertyMap}}{{^propertyMap}}value{{/propertyMap}}("{{baseName}}"_ls)); - {{/vars}}{{#propertyMap}} - result.{{nameCamelCase}} = fromJson<{{dataType.name}}>(_json);{{/propertyMap}} +{{#vars}} result.{{nameCamelCase}} = + fromJson<{{dataType.qualifiedName}}>(jo.{{#propertyMap}}take{{/propertyMap}}{{^propertyMap}}value{{/propertyMap}}("{{baseName}}"_ls)); +{{/vars}}{{#propertyMap}} + result.{{nameCamelCase}} = fromJson<{{dataType.qualifiedName}}>(jo);{{/propertyMap}} return result; } {{/out?}}{{/models.model}}{{#operations}} @@ -34,20 +33,20 @@ namespace QMatrixClient {{#model}}{{#in?}} QJsonObject toJson(const {{qualifiedName}}& pod) { - QJsonObject _json;{{#vars}} - addParam<{{^required?}}IfNotEmpty{{/required?}}>(_json, QStringLiteral("{{baseName}}"), pod.{{nameCamelCase}});{{/vars}} - return _json; + QJsonObject jo{{#propertyMap}} = toJson(pod.{{nameCamelCase}}){{/propertyMap}};{{#vars}} + addParam<{{^required?}}IfNotEmpty{{/required?}}>(jo, QStringLiteral("{{baseName}}"), pod.{{nameCamelCase}});{{/vars}} + return jo; } {{/in?}}{{#out?}} - template <> struct FromJson<{{qualifiedName}}> + template <> struct FromJsonObject<{{qualifiedName}}> { - {{qualifiedName}} operator()(const QJsonValue& jv) + {{qualifiedName}} operator()({{^propertyMap}}const QJsonObject&{{/propertyMap}}{{#propertyMap}}QJsonObject{{/propertyMap}} jo) const { - const auto& _json = jv.toObject(); {{qualifiedName}} result; {{#vars}} result.{{nameCamelCase}} = - fromJson<{{dataType.qualifiedName}}>(_json.value("{{baseName}}"_ls)); -{{/vars}} + fromJson<{{dataType.qualifiedName}}>(jo.{{#propertyMap}}take{{/propertyMap}}{{^propertyMap}}value{{/propertyMap}}("{{baseName}}"_ls)); +{{/vars}}{{#propertyMap}} + result.{{nameCamelCase}} = fromJson<{{dataType.qualifiedName}}>(jo);{{/propertyMap}} return result; } }; @@ -104,17 +103,18 @@ static const auto {{camelCaseOperationId}}JobName = QStringLiteral("{{camelCaseO {{/ allProperties}}{{#producesNonJson?}} BaseJob::Status {{camelCaseOperationId}}Job::parseReply(QNetworkReply* reply) { - {{#headers}}d->{{paramName}} = reply->rawHeader("{{baseName}}"); {{! We don't check for required headers yet }} + {{#headers}}d->{{paramName}} = reply->rawHeader("{{baseName}}");{{! We don't check for required headers yet }} {{/headers}}{{#properties}}d->{{paramName}} = reply;{{/properties}} return Success; }{{/ producesNonJson?}}{{^producesNonJson?}} BaseJob::Status {{camelCaseOperationId}}Job::parseJson(const QJsonDocument& data) { - auto json = data.object(); - {{# properties}}{{#required?}}if (!json.contains("{{baseName}}"_ls)) +{{#inlineResponse}} d->{{paramName}} = fromJson<{{dataType.name}}>(data); +{{/inlineResponse}}{{^inlineResponse}} auto json = data.object(); +{{#properties}}{{#required?}} if (!json.contains("{{baseName}}"_ls)) return { JsonParseError, "The key '{{baseName}}' not found in the response" }; - {{/required?}}d->{{paramName}} = fromJson<{{dataType.name}}>(json.value("{{baseName}}"_ls)); - {{/ properties}}return Success; +{{/required?}} d->{{paramName}} = fromJson<{{dataType.name}}>(json.value("{{baseName}}"_ls)); +{{/properties}}{{/inlineResponse}} return Success; }{{/ producesNonJson?}} {{/allProperties?}}{{/normalResponse?}}{{/responses}}{{/operation}}{{/operations}} diff --git a/lib/csapi/{{base}}.h.mustache b/lib/csapi/{{base}}.h.mustache index d6b374fb..147c8607 100644 --- a/lib/csapi/{{base}}.h.mustache +++ b/lib/csapi/{{base}}.h.mustache @@ -21,15 +21,15 @@ namespace QMatrixClient {{#in?}} QJsonObject toJson(const {{name}}& pod); {{/in?}}{{#out?}} - template <> struct FromJson<{{name}}> + template <> struct FromJsonObject<{{name}}> { - {{name}} operator()(const QJsonValue& jv); + {{name}} operator()({{^propertyMap}}const QJsonObject&{{/propertyMap}}{{#propertyMap}}QJsonObject{{/propertyMap}} jo) const; }; {{/ out?}}{{/model}} {{/models}}{{#operations}} // Operations {{# operation}}{{#summary}} /// {{summary}}{{#description?}}{{!add a linebreak between summary and description if both exist}} - /// {{/description?}}{{/summary}}{{#description}} + ///{{/description?}}{{/summary}}{{#description}} /// {{_}}{{/description}} class {{camelCaseOperationId}}Job : public BaseJob { @@ -48,7 +48,7 @@ namespace QMatrixClient // Construction/destruction {{/ models}}{{#allParams?}} /*! {{summary}}{{#allParams}} - * \param {{nameCamelCase}} {{#description}} + * \param {{nameCamelCase}}{{#description}} * {{_}}{{/description}}{{/allParams}} */{{/allParams?}} explicit {{camelCaseOperationId}}Job({{#allParams}}{{>joinedParamDecl}}{{/allParams}});{{^bodyParams}} diff --git a/lib/events/accountdataevents.h b/lib/events/accountdataevents.h index 27f6c77c..792ea7f7 100644 --- a/lib/events/accountdataevents.h +++ b/lib/events/accountdataevents.h @@ -36,11 +36,11 @@ namespace QMatrixClient order_type order; TagRecord (order_type order = none) : order(order) { } - explicit TagRecord(const QJsonValue& jv) + explicit TagRecord(const QJsonObject& jo) { // Parse a float both from JSON double and JSON string because // libqmatrixclient previously used to use strings to store order. - const auto orderJv = jv.toObject().value("order"_ls); + const auto orderJv = jo.value("order"_ls); if (orderJv.isDouble()) order = fromJson<float>(orderJv); else if (orderJv.isString()) diff --git a/lib/events/eventloader.h b/lib/events/eventloader.h index ea261cac..3ee9a181 100644 --- a/lib/events/eventloader.h +++ b/lib/events/eventloader.h @@ -58,11 +58,11 @@ namespace QMatrixClient { matrixType); } - template <typename EventT> struct FromJson<event_ptr_tt<EventT>> + template <typename EventT> struct FromJsonObject<event_ptr_tt<EventT>> { - auto operator()(const QJsonValue& jv) const + auto operator()(const QJsonObject& jo) const { - return loadEvent<EventT>(jv.toObject()); + return loadEvent<EventT>(jo); } }; } // namespace QMatrixClient diff --git a/lib/identity/definitions/request_email_validation.cpp b/lib/identity/definitions/request_email_validation.cpp new file mode 100644 index 00000000..95088bcb --- /dev/null +++ b/lib/identity/definitions/request_email_validation.cpp @@ -0,0 +1,33 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + +#include "request_email_validation.h" + +using namespace QMatrixClient; + +QJsonObject QMatrixClient::toJson(const RequestEmailValidation& pod) +{ + QJsonObject jo; + addParam<>(jo, QStringLiteral("client_secret"), pod.clientSecret); + addParam<>(jo, QStringLiteral("email"), pod.email); + addParam<>(jo, QStringLiteral("send_attempt"), pod.sendAttempt); + addParam<IfNotEmpty>(jo, QStringLiteral("next_link"), pod.nextLink); + return jo; +} + +RequestEmailValidation FromJsonObject<RequestEmailValidation>::operator()(const QJsonObject& jo) const +{ + RequestEmailValidation result; + result.clientSecret = + fromJson<QString>(jo.value("client_secret"_ls)); + result.email = + fromJson<QString>(jo.value("email"_ls)); + result.sendAttempt = + fromJson<int>(jo.value("send_attempt"_ls)); + result.nextLink = + fromJson<QString>(jo.value("next_link"_ls)); + + return result; +} + diff --git a/lib/identity/definitions/request_email_validation.h b/lib/identity/definitions/request_email_validation.h new file mode 100644 index 00000000..3e72275f --- /dev/null +++ b/lib/identity/definitions/request_email_validation.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + +#pragma once + +#include "converters.h" + +#include "converters.h" + +namespace QMatrixClient +{ + // Data structures + + struct RequestEmailValidation + { + /// 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. + QString clientSecret; + /// The email address to validate. + QString email; + /// 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. + int sendAttempt; + /// Optional. When the validation is completed, the identity + /// server will redirect the user to this URL. + QString nextLink; + }; + + QJsonObject toJson(const RequestEmailValidation& pod); + + template <> struct FromJsonObject<RequestEmailValidation> + { + RequestEmailValidation operator()(const QJsonObject& jo) const; + }; + +} // namespace QMatrixClient diff --git a/lib/identity/definitions/request_msisdn_validation.cpp b/lib/identity/definitions/request_msisdn_validation.cpp new file mode 100644 index 00000000..125baa9c --- /dev/null +++ b/lib/identity/definitions/request_msisdn_validation.cpp @@ -0,0 +1,36 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + +#include "request_msisdn_validation.h" + +using namespace QMatrixClient; + +QJsonObject QMatrixClient::toJson(const RequestMsisdnValidation& pod) +{ + QJsonObject jo; + addParam<>(jo, QStringLiteral("client_secret"), pod.clientSecret); + addParam<>(jo, QStringLiteral("country"), pod.country); + addParam<>(jo, QStringLiteral("phone_number"), pod.phoneNumber); + addParam<>(jo, QStringLiteral("send_attempt"), pod.sendAttempt); + addParam<IfNotEmpty>(jo, QStringLiteral("next_link"), pod.nextLink); + return jo; +} + +RequestMsisdnValidation FromJsonObject<RequestMsisdnValidation>::operator()(const QJsonObject& jo) const +{ + RequestMsisdnValidation result; + result.clientSecret = + fromJson<QString>(jo.value("client_secret"_ls)); + result.country = + fromJson<QString>(jo.value("country"_ls)); + result.phoneNumber = + fromJson<QString>(jo.value("phone_number"_ls)); + result.sendAttempt = + fromJson<int>(jo.value("send_attempt"_ls)); + result.nextLink = + fromJson<QString>(jo.value("next_link"_ls)); + + return result; +} + diff --git a/lib/identity/definitions/request_msisdn_validation.h b/lib/identity/definitions/request_msisdn_validation.h new file mode 100644 index 00000000..77bea2bc --- /dev/null +++ b/lib/identity/definitions/request_msisdn_validation.h @@ -0,0 +1,47 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + +#pragma once + +#include "converters.h" + +#include "converters.h" + +namespace QMatrixClient +{ + // Data structures + + struct RequestMsisdnValidation + { + /// 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. + QString clientSecret; + /// The two-letter uppercase ISO country code that the number in + /// ``phone_number`` should be parsed as if it were dialled from. + QString country; + /// The phone number to validate. + QString phoneNumber; + /// 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. + int sendAttempt; + /// Optional. When the validation is completed, the identity + /// server will redirect the user to this URL. + QString nextLink; + }; + + QJsonObject toJson(const RequestMsisdnValidation& pod); + + template <> struct FromJsonObject<RequestMsisdnValidation> + { + RequestMsisdnValidation operator()(const QJsonObject& jo) const; + }; + +} // namespace QMatrixClient diff --git a/lib/identity/definitions/sid.cpp b/lib/identity/definitions/sid.cpp new file mode 100644 index 00000000..443dbedf --- /dev/null +++ b/lib/identity/definitions/sid.cpp @@ -0,0 +1,24 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + +#include "sid.h" + +using namespace QMatrixClient; + +QJsonObject QMatrixClient::toJson(const Sid& pod) +{ + QJsonObject jo; + addParam<>(jo, QStringLiteral("sid"), pod.sid); + return jo; +} + +Sid FromJsonObject<Sid>::operator()(const QJsonObject& jo) const +{ + Sid result; + result.sid = + fromJson<QString>(jo.value("sid"_ls)); + + return result; +} + diff --git a/lib/identity/definitions/sid.h b/lib/identity/definitions/sid.h new file mode 100644 index 00000000..eae60c47 --- /dev/null +++ b/lib/identity/definitions/sid.h @@ -0,0 +1,30 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ + +#pragma once + +#include "converters.h" + + +namespace QMatrixClient +{ + // Data structures + + struct Sid + { + /// The session ID. Session IDs are opaque strings generated by the identity + /// server. They must consist entirely of the characters + /// ``[0-9a-zA-Z.=_-]``. Their length must not exceed 255 characters and they + /// must not be empty. + QString sid; + }; + + QJsonObject toJson(const Sid& pod); + + template <> struct FromJsonObject<Sid> + { + Sid operator()(const QJsonObject& jo) const; + }; + +} // namespace QMatrixClient diff --git a/lib/room.cpp b/lib/room.cpp index b7e8195d..2e409124 100644 --- a/lib/room.cpp +++ b/lib/room.cpp @@ -726,7 +726,7 @@ void Room::addTag(const QString& name, const TagRecord& record) d->sendTagUpdates(); } -void Room::addTag(const QString& name, const QString& order) +void Room::addTag(const QString& name, TagRecord::order_type order) { addTag(name, TagRecord{order}); } @@ -262,7 +262,8 @@ namespace QMatrixClient * clients. */ void addTag(const QString& name, const TagRecord& record = {}); - Q_INVOKABLE void addTag(const QString& name, const QString& order); + Q_INVOKABLE void addTag(const QString& name, + TagRecord::order_type order); /// Remove a tag from the room Q_INVOKABLE void removeTag(const QString& name); diff --git a/libqmatrixclient.pri b/libqmatrixclient.pri index 2bb3b499..cb90a9fd 100644 --- a/libqmatrixclient.pri +++ b/libqmatrixclient.pri @@ -44,7 +44,9 @@ HEADERS += \ $$SRCPATH/jobs/postreadmarkersjob.h \ $$files($$SRCPATH/csapi/*.h, false) \ $$files($$SRCPATH/csapi/definitions/*.h, false) \ + $$files($$SRCPATH/csapi/definitions/wellknown/*.h, false) \ $$files($$SRCPATH/application-service/definitions/*.h, false) \ + $$files($$SRCPATH/identity/definitions/*.h, false) \ $$SRCPATH/logging.h \ $$SRCPATH/converters.h \ $$SRCPATH/settings.h \ @@ -79,7 +81,9 @@ SOURCES += \ $$SRCPATH/jobs/downloadfilejob.cpp \ $$files($$SRCPATH/csapi/*.cpp, false) \ $$files($$SRCPATH/csapi/definitions/*.cpp, false) \ + $$files($$SRCPATH/csapi/definitions/wellknown/*.cpp, false) \ $$files($$SRCPATH/application-service/definitions/*.cpp, false) \ + $$files($$SRCPATH/identity/definitions/*.cpp, false) \ $$SRCPATH/logging.cpp \ $$SRCPATH/converters.cpp \ $$SRCPATH/settings.cpp \ |