aboutsummaryrefslogtreecommitdiff
path: root/jobs/basejob.h
AgeCommit message (Collapse)Author
2016-07-27Introduce Status class + BaseJob::{checkReply,parseReply,parseJson} now ↵Kitsune Ral
return it This better fixes the contract for derived job classes and simplifies error reporting. Methods error() and errorString() are kept for back-compatibility; status() returns a combination of them, conveniently packed into a Status object. For a quick status check, Status::good() is provided.
2016-07-26Split BaseJob::gotReply into checkReply and parseReply + internal tweaks to ↵Kitsune Ral
BaseJob 1. The externally (for derived classes) visible additions are checkReply() and parseReply() virtual methods, with gotReply becoming a mere dispatcher (and therefore a private method). Splitting gotReply() in that way allowed to remove boilerplate code from MediaThumbnailJob. 2. The internal tweak is using QScopedPointer<> to store pointers both to the Private object and to a QNetworkReply (with a special deleter that aborts the reply before destructing the object). This allows to remove desperate attempts to call reply->abort() wherever it's no more needed (and not aborting the in-flight replies seems to be a/the culprit of Quaternion after-exit hangs).
2016-07-26Rewritten BaseJob to not depend on KJob.Kitsune Ral
Some parts of the code were copied from the KCoreAddons sources - surprisingly few, in fact, mostly API with comments. With this commit, libqmatrixclient doesn't depend on KCoreAddons.
2016-07-22Separate errors of access denial kind to a different BaseJob error code as ↵Kitsune Ral
well + stability fixes 1. Introduce ContentAccessDenied error code to BaseJob to allow clients to treat access denial errors differently from other network errors. 2. Since parseJson() overrides are responsible for calling emitResult(), the "default" BaseJob::parseJson() should call emitResult() as well. 3. Make sure BaseJob::fail() doesn't crash in absence of QNetworkReply.
2016-05-27Use 'override' keyword throughout job classes; constify apiPath(), query(), ↵Kitsune Ral
data() Thanks to CLang model.
2016-05-27Set the object name for each job, to make it clear which job has failedKitsune Ral
And we don't need two log lines for timeouts.
2016-05-06Make sure the QNetworkReply object is aborted at any failure and even silent ↵Kitsune Ral
destruction of the job
2016-05-06Add separate success() and failure() signals to BaseJobKitsune Ral
This is to facilitate processing of job results (see further commits).
2016-04-12Resolve Matrix SRV records.David A Roberts
2016-04-05Imported the current source tree from Quaternion/lib.Kitsune Ral
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
/******************************************************************************
 * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN
 */

#pragma once

#include "e2ee/e2ee.h"

#include "csapi/definitions/cross_signing_key.h"
#include "csapi/definitions/device_keys.h"

#include "jobs/basejob.h"

namespace Quotient {

/*! \brief Upload end-to-end encryption keys.
 *
 * Publishes end-to-end encryption keys for the device.
 */
class QUOTIENT_API 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](/client-server-api/#key-algorithms).
     *
     *   May be absent if no new one-time keys are required.
     *
     * \param fallbackKeys
     *   The public key which should be used if the device's one-time keys
     *   are exhausted. The fallback key is not deleted once used, but should
     *   be replaced when additional one-time keys are being uploaded. The
     *   server will notify the client of the fallback key being used through
     *   `/sync`.
     *
     *   There can only be at most one key per algorithm uploaded, and the
     * server will only persist one key per algorithm.
     *
     *   When uploading a signed key, an additional `fallback: true` key should
     *   be included to denote that the key is a fallback key.
     *
     *   May be absent if a new fallback key is not required.
     */
    explicit UploadKeysJob(const Omittable<DeviceKeys>& deviceKeys = none,
                           const OneTimeKeys& oneTimeKeys = {},
                           const OneTimeKeys& fallbackKeys = {});

    // Result properties

    /// For each key algorithm, the number of unclaimed one-time keys
    /// of that type currently held on the server for this device.
    /// If an algorithm is not listed, the count for that algorithm
    /// is to be assumed zero.
    QHash<QString, int> oneTimeKeyCounts() const
    {
        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 QUOTIENT_API 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

    /*! \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.
    ///
    /// 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
    {
        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);
    }

    /// Information on the master cross-signing keys of the queried users.
    /// A map from user ID, to master key information.  For each key, the
    /// information returned will be the same as uploaded via
    /// `/keys/device_signing/upload`, along with the signatures
    /// uploaded via `/keys/signatures/upload` that the requesting user
    /// is allowed to see.
    QHash<QString, CrossSigningKey> masterKeys() const
    {
        return loadFromJson<QHash<QString, CrossSigningKey>>("master_keys"_ls);
    }

    /// Information on the self-signing keys of the queried users. A map
    /// from user ID, to self-signing key information.  For each key, the
    /// information returned will be the same as uploaded via
    /// `/keys/device_signing/upload`.
    QHash<QString, CrossSigningKey> selfSigningKeys() const
    {
        return loadFromJson<QHash<QString, CrossSigningKey>>(
            "self_signing_keys"_ls);
    }

    /// Information on the user-signing key of the user making the
    /// request, if they queried their own device information. A map
    /// from user ID, to user-signing key information.  The
    /// information returned will be the same as uploaded via
    /// `/keys/device_signing/upload`.
    QHash<QString, CrossSigningKey> userSigningKeys() const
    {
        return loadFromJson<QHash<QString, CrossSigningKey>>(
            "user_signing_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 QUOTIENT_API 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);
    }

    /// 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.
    ///
    /// See the [key algorithms](/client-server-api/#key-algorithms) section for
    /// information on the Key Object format.
    ///
    /// If necessary, the claimed key might be a fallback key. Fallback
    /// keys are re-used by the server until replaced by the device.
    QHash<QString, QHash<QString, OneTimeKeys>> oneTimeKeys() const
    {
        return loadFromJson<QHash<QString, QHash<QString, OneTimeKeys>>>(
            "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 QUOTIENT_API 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`](/client-server-api/#get_matrixclientv3sync). 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`](/client-server-api/#get_matrixclientv3sync) - 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