diff options
Diffstat (limited to 'lib/csapi/keys.h')
-rw-r--r-- | lib/csapi/keys.h | 418 |
1 files changed, 219 insertions, 199 deletions
diff --git a/lib/csapi/keys.h b/lib/csapi/keys.h index e59b1dae..8f6c8cc9 100644 --- a/lib/csapi/keys.h +++ b/lib/csapi/keys.h @@ -4,216 +4,236 @@ #pragma once -#include "jobs/basejob.h" - #include "csapi/definitions/device_keys.h" -#include <QtCore/QHash> -#include "converters.h" -#include <QtCore/QVariant> -#include <QtCore/QJsonObject> -namespace QMatrixClient -{ - // Operations +#include "jobs/basejob.h" + +namespace Quotient { - /// Upload end-to-end encryption keys. - /// - /// Publishes end-to-end encryption keys for the device. - class UploadKeysJob : public BaseJob +/*! \brief Upload end-to-end encryption keys. + * + * Publishes end-to-end encryption keys for the device. + */ +class UploadKeysJob : public BaseJob { +public: + /*! \brief Upload end-to-end encryption keys. + * + * \param deviceKeys + * Identity keys for the device. May be absent if no new + * identity keys are required. + * + * \param oneTimeKeys + * One-time public keys for "pre-key" messages. The names of + * the properties should be in the format + * ``<algorithm>:<key_id>``. The format of the key is determined + * by the `key algorithm <#key-algorithms>`_. + * + * May be absent if no new one-time keys are required. + */ + explicit UploadKeysJob(const Omittable<DeviceKeys>& deviceKeys = none, + const QHash<QString, QVariant>& oneTimeKeys = {}); + + // Result properties + + /// For each key algorithm, the number of unclaimed one-time keys + /// of that type currently held on the server for this device. + QHash<QString, int> oneTimeKeyCounts() const { - public: - /*! Upload end-to-end encryption keys. - * \param deviceKeys - * Identity keys for the device. May be absent if no new - * identity keys are required. - * \param oneTimeKeys - * One-time public keys for "pre-key" messages. The names of - * the properties should be in the format - * ``<algorithm>:<key_id>``. The format of the key is determined - * by the key algorithm. - * - * May be absent if no new one-time keys are required. - */ - explicit UploadKeysJob(const Omittable<DeviceKeys>& deviceKeys = none, const QHash<QString, QVariant>& oneTimeKeys = {}); - ~UploadKeysJob() override; - - // Result properties - - /// For each key algorithm, the number of unclaimed one-time keys - /// of that type currently held on the server for this device. - const QHash<QString, int>& oneTimeKeyCounts() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; + return loadFromJson<QHash<QString, int>>("one_time_key_counts"_ls); + } +}; + +/*! \brief Download device identity keys. + * + * Returns the current devices and identity keys for the given users. + */ +class QueryKeysJob : public BaseJob { +public: + // Inner data structures + + /// Additional data added to the device key information + /// by intermediate servers, and not covered by the + /// signatures. + struct UnsignedDeviceInfo { + /// The display name which the user set on the device. + QString deviceDisplayName; }; - /// Download device identity keys. - /// /// Returns the current devices and identity keys for the given users. - class QueryKeysJob : public BaseJob - { - public: - // Inner data structures - - /// Additional data added to the device key information - /// by intermediate servers, and not covered by the - /// signatures. - struct UnsignedDeviceInfo - { - /// The display name which the user set on the device. - QString deviceDisplayName; - }; - - /// Returns the current devices and identity keys for the given users. - struct DeviceInformation : DeviceKeys - { - /// Additional data added to the device key information - /// by intermediate servers, and not covered by the - /// signatures. - Omittable<UnsignedDeviceInfo> unsignedData; - }; - - // Construction/destruction - - /*! Download device identity keys. - * \param deviceKeys - * The keys to be downloaded. A map from user ID, to a list of - * device IDs, or to an empty list to indicate all devices for the - * corresponding user. - * \param timeout - * The time (in milliseconds) to wait when downloading keys from - * remote servers. 10 seconds is the recommended default. - * \param token - * If the client is fetching keys as a result of a device update received - * in a sync request, this should be the 'since' token of that sync request, - * or any later sync token. This allows the server to ensure its response - * contains the keys advertised by the notification in that sync. - */ - explicit QueryKeysJob(const QHash<QString, QStringList>& deviceKeys, Omittable<int> timeout = none, const QString& token = {}); - ~QueryKeysJob() override; - - // Result properties - - /// If any remote homeservers could not be reached, they are - /// recorded here. The names of the properties are the names of - /// the unreachable servers. - /// - /// If the homeserver could be reached, but the user or device - /// was unknown, no failure is recorded. Instead, the corresponding - /// user or device is missing from the ``device_keys`` result. - const QHash<QString, QJsonObject>& failures() const; - /// Information on the queried devices. A map from user ID, to a - /// map from device ID to device information. For each device, - /// the information returned will be the same as uploaded via - /// ``/keys/upload``, with the addition of an ``unsigned`` - /// property. - const QHash<QString, QHash<QString, DeviceInformation>>& deviceKeys() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; + struct DeviceInformation : DeviceKeys { + /// Additional data added to the device key information + /// by intermediate servers, and not covered by the + /// signatures. + Omittable<UnsignedDeviceInfo> unsignedData; }; - /// Claim one-time encryption keys. + // Construction/destruction + + /*! \brief Download device identity keys. + * + * \param deviceKeys + * The keys to be downloaded. A map from user ID, to a list of + * device IDs, or to an empty list to indicate all devices for the + * corresponding user. + * + * \param timeout + * The time (in milliseconds) to wait when downloading keys from + * remote servers. 10 seconds is the recommended default. + * + * \param token + * If the client is fetching keys as a result of a device update received + * in a sync request, this should be the 'since' token of that sync + * request, or any later sync token. This allows the server to ensure its + * response contains the keys advertised by the notification in that sync. + */ + explicit QueryKeysJob(const QHash<QString, QStringList>& deviceKeys, + Omittable<int> timeout = none, + const QString& token = {}); + + // Result properties + + /// If any remote homeservers could not be reached, they are + /// recorded here. The names of the properties are the names of + /// the unreachable servers. /// - /// Claims one-time keys for use in pre-key messages. - class ClaimKeysJob : public BaseJob + /// If the homeserver could be reached, but the user or device + /// was unknown, no failure is recorded. Instead, the corresponding + /// user or device is missing from the ``device_keys`` result. + QHash<QString, QJsonObject> failures() const { - public: - /*! Claim one-time encryption keys. - * \param oneTimeKeys - * The keys to be claimed. A map from user ID, to a map from - * device ID to algorithm name. - * \param timeout - * The time (in milliseconds) to wait when downloading keys from - * remote servers. 10 seconds is the recommended default. - */ - explicit ClaimKeysJob(const QHash<QString, QHash<QString, QString>>& oneTimeKeys, Omittable<int> timeout = none); - ~ClaimKeysJob() override; - - // Result properties - - /// If any remote homeservers could not be reached, they are - /// recorded here. The names of the properties are the names of - /// the unreachable servers. - /// - /// If the homeserver could be reached, but the user or device - /// was unknown, no failure is recorded. Instead, the corresponding - /// user or device is missing from the ``one_time_keys`` result. - const QHash<QString, QJsonObject>& failures() const; - /// One-time keys for the queried devices. A map from user ID, to a - /// map from devices to a map from ``<algorithm>:<key_id>`` to the key object. - const QHash<QString, QHash<QString, QVariant>>& oneTimeKeys() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; + return loadFromJson<QHash<QString, QJsonObject>>("failures"_ls); + } + + /// Information on the queried devices. A map from user ID, to a + /// map from device ID to device information. For each device, + /// the information returned will be the same as uploaded via + /// ``/keys/upload``, with the addition of an ``unsigned`` + /// property. + QHash<QString, QHash<QString, DeviceInformation>> deviceKeys() const + { + return loadFromJson<QHash<QString, QHash<QString, DeviceInformation>>>( + "device_keys"_ls); + } +}; + +template <> +struct JsonObjectConverter<QueryKeysJob::UnsignedDeviceInfo> { + static void fillFrom(const QJsonObject& jo, + QueryKeysJob::UnsignedDeviceInfo& result) + { + fromJson(jo.value("device_display_name"_ls), result.deviceDisplayName); + } +}; + +template <> +struct JsonObjectConverter<QueryKeysJob::DeviceInformation> { + static void fillFrom(const QJsonObject& jo, + QueryKeysJob::DeviceInformation& result) + { + fillFromJson<DeviceKeys>(jo, result); + fromJson(jo.value("unsigned"_ls), result.unsignedData); + } +}; + +/*! \brief Claim one-time encryption keys. + * + * Claims one-time keys for use in pre-key messages. + */ +class ClaimKeysJob : public BaseJob { +public: + /*! \brief Claim one-time encryption keys. + * + * \param oneTimeKeys + * The keys to be claimed. A map from user ID, to a map from + * device ID to algorithm name. + * + * \param timeout + * The time (in milliseconds) to wait when downloading keys from + * remote servers. 10 seconds is the recommended default. + */ + explicit ClaimKeysJob( + const QHash<QString, QHash<QString, QString>>& oneTimeKeys, + Omittable<int> timeout = none); + + // Result properties + + /// If any remote homeservers could not be reached, they are + /// recorded here. The names of the properties are the names of + /// the unreachable servers. + /// + /// If the homeserver could be reached, but the user or device + /// was unknown, no failure is recorded. Instead, the corresponding + /// user or device is missing from the ``one_time_keys`` result. + QHash<QString, QJsonObject> failures() const + { + return loadFromJson<QHash<QString, QJsonObject>>("failures"_ls); + } - /// Query users with recent device key updates. + /// One-time keys for the queried devices. A map from user ID, to a + /// map from devices to a map from ``<algorithm>:<key_id>`` to the key + /// object. /// - /// Gets a list of users who have updated their device identity keys since a - /// previous sync token. - /// - /// The server should include in the results any users who: - /// - /// * currently share a room with the calling user (ie, both users have - /// membership state ``join``); *and* - /// * added new device identity keys or removed an existing device with - /// identity keys, between ``from`` and ``to``. - class GetKeysChangesJob : public BaseJob + /// See the `key algorithms <#key-algorithms>`_ section for information + /// on the Key Object format. + QHash<QString, QHash<QString, QVariant>> oneTimeKeys() const { - public: - /*! Query users with recent device key updates. - * \param from - * The desired start point of the list. Should be the ``next_batch`` field - * from a response to an earlier call to |/sync|. Users who have not - * uploaded new device identity keys since this point, nor deleted - * existing devices with identity keys since then, will be excluded - * from the results. - * \param to - * The desired end point of the list. Should be the ``next_batch`` - * field from a recent call to |/sync| - typically the most recent - * such call. This may be used by the server as a hint to check its - * caches are up to date. - */ - explicit GetKeysChangesJob(const QString& from, const QString& to); - - /*! Construct a URL without creating a full-fledged job object - * - * This function can be used when a URL for - * GetKeysChangesJob is necessary but the job - * itself isn't. - */ - static QUrl makeRequestUrl(QUrl baseUrl, const QString& from, const QString& to); - - ~GetKeysChangesJob() override; - - // Result properties - - /// The Matrix User IDs of all users who updated their device - /// identity keys. - const QStringList& changed() const; - /// The Matrix User IDs of all users who may have left all - /// the end-to-end encrypted rooms they previously shared - /// with the user. - const QStringList& left() const; - - protected: - Status parseJson(const QJsonDocument& data) override; - - private: - class Private; - QScopedPointer<Private> d; - }; -} // namespace QMatrixClient + return loadFromJson<QHash<QString, QHash<QString, QVariant>>>( + "one_time_keys"_ls); + } +}; + +/*! \brief Query users with recent device key updates. + * + * Gets a list of users who have updated their device identity keys since a + * previous sync token. + * + * The server should include in the results any users who: + * + * * currently share a room with the calling user (ie, both users have + * membership state ``join``); *and* + * * added new device identity keys or removed an existing device with + * identity keys, between ``from`` and ``to``. + */ +class GetKeysChangesJob : public BaseJob { +public: + /*! \brief Query users with recent device key updates. + * + * \param from + * The desired start point of the list. Should be the ``next_batch`` field + * from a response to an earlier call to |/sync|. Users who have not + * uploaded new device identity keys since this point, nor deleted + * existing devices with identity keys since then, will be excluded + * from the results. + * + * \param to + * The desired end point of the list. Should be the ``next_batch`` + * field from a recent call to |/sync| - typically the most recent + * such call. This may be used by the server as a hint to check its + * caches are up to date. + */ + explicit GetKeysChangesJob(const QString& from, const QString& to); + + /*! \brief Construct a URL without creating a full-fledged job object + * + * This function can be used when a URL for GetKeysChangesJob + * is necessary but the job itself isn't. + */ + static QUrl makeRequestUrl(QUrl baseUrl, const QString& from, + const QString& to); + + // Result properties + + /// The Matrix User IDs of all users who updated their device + /// identity keys. + QStringList changed() const + { + return loadFromJson<QStringList>("changed"_ls); + } + + /// The Matrix User IDs of all users who may have left all + /// the end-to-end encrypted rooms they previously shared + /// with the user. + QStringList left() const { return loadFromJson<QStringList>("left"_ls); } +}; + +} // namespace Quotient |