matrix_sdk/encryption/recovery/
types.rs

1// Copyright 2023 The Matrix.org Foundation C.I.C.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use matrix_sdk_base::crypto::store::types::RoomKeyCounts;
16use ruma::events::macros::EventContent;
17use serde::{Deserialize, Serialize};
18use thiserror::Error;
19use zeroize::{Zeroize, ZeroizeOnDrop};
20
21#[cfg(doc)]
22use crate::encryption::{
23    backups::Backups,
24    recovery::{futures::Enable, Recovery},
25};
26
27/// Result type alias for the [`Recovery`] subsystem.
28pub type Result<A, E = RecoveryError> = std::result::Result<A, E>;
29
30/// Error type for the [`Recovery`] subsystem.
31#[derive(Debug, Error)]
32pub enum RecoveryError {
33    /// A backup already exists on the homeserver, the recovery subsystem does
34    /// not allow backups to be overwritten, disable recovery first.
35    #[error(
36        "A backup already exists on the homeserver and the method does not allow to overwrite it"
37    )]
38    BackupExistsOnServer,
39
40    /// A typical SDK error.
41    #[error(transparent)]
42    Sdk(#[from] crate::Error),
43
44    /// Error in the secret storage subsystem.
45    #[error(transparent)]
46    SecretStorage(#[from] crate::encryption::secret_storage::SecretStorageError),
47}
48
49/// Enum describing the states the [`Recovery::enable()`] method can be in.
50#[derive(Debug, Default, Clone, Zeroize, ZeroizeOnDrop)]
51pub enum EnableProgress {
52    /// The client is just starting the process of enabling recovery, this is
53    /// the initial state.
54    #[default]
55    Starting,
56    /// The client is creating a new server-side key backup.
57    CreatingBackup,
58    /// The client is creating a new recovery key and uploading all the locally
59    /// cached secrets to the homeserver.
60    CreatingRecoveryKey,
61    /// The client is currently backing up room keys to the server-side key
62    /// backup. This state may be emitted multiple times until all room keys
63    /// have been backed up.
64    #[zeroize(skip)]
65    BackingUp(RoomKeyCounts),
66    /// The client encountered an error while trying to upload all room keys to
67    /// the server-side key backup.
68    ///
69    /// Not all room keys may have been backed up, the client will try to back
70    /// them up again at a later point. If you'd like to wait for the backup
71    /// to finish again you can use the [`Backups::wait_for_steady_state()`]
72    /// method.
73    RoomKeyUploadError,
74    /// Recovery has been successfully enabled, this is the final state.
75    Done {
76        /// The newly created recovery key.
77        // TODO: Can I remove this from here? It seems a bit dumb.
78        recovery_key: String,
79    },
80}
81
82/// The states the recovery subsystem can be in.
83///
84/// You can listen on the state of the recovery mechanism using the
85/// [`Recovery::state_stream()`] method.
86#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
87pub enum RecoveryState {
88    /// We didn't yet inform ourselves about the state of things.
89    #[default]
90    Unknown,
91    /// Secret storage is set up and we have all the secrets locally.
92    Enabled,
93    /// No default secret storage key exists or it is disabled explicitly using
94    /// the account data event.
95    Disabled,
96    /// Secret storage is set up but we're missing some secrets.
97    Incomplete,
98}
99
100/// A hack to allow the `m.secret_storage.default_key` event to be "deleted".
101///
102/// This allows us to set the `m.secret_storage.default_key` event to an empty
103/// JSON object, which means that the event will be invalid.
104#[derive(Clone, Debug, Default, Deserialize, Serialize, EventContent)]
105#[ruma_event(type = "m.secret_storage.default_key", kind = GlobalAccountData)]
106pub(super) struct SecretStorageDisabledContent {}
107
108/// A custom global account data event which tells us that a new backup should
109/// not be automatically created.
110#[derive(Clone, Debug, Default, Deserialize, Serialize, EventContent)]
111#[ruma_event(type = "m.org.matrix.custom.backup_disabled", kind = GlobalAccountData)]
112pub(super) struct BackupDisabledContent {
113    pub disabled: bool,
114}