matrix_sdk/encryption/verification/
mod.rs

1// Copyright 2021 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
15//! Interactive verification for E2EE capable users and devices in Matrix.
16//!
17//! The SDK supports interactive verification of devices and users, this module
18//! contains types that model and support different verification flows.
19//!
20//! A verification flow usually starts its life as a [VerificationRequest], the
21//! request can then be accepted, or it needs to be accepted by the other side
22//! of the verification flow.
23//!
24//! Once both sides have agreed to perform the verification, and the
25//! [VerificationRequest::is_ready()] method returns true, the verification can
26//! transition into one of the supported verification flows:
27//!
28//! * [`SasVerification`] - Interactive verification using a short
29//!   authentication string.
30//! * [`QrVerification`] - Interactive verification using QR codes.
31
32#[cfg(feature = "qrcode")]
33mod qrcode;
34mod requests;
35mod sas;
36
37use as_variant::as_variant;
38pub use matrix_sdk_base::crypto::{
39    format_emojis, AcceptSettings, AcceptedProtocols, CancelInfo, Emoji, EmojiShortAuthString,
40    SasState,
41};
42#[cfg(feature = "qrcode")]
43pub use matrix_sdk_base::crypto::{
44    matrix_sdk_qrcode::{DecodingError, EncodingError, QrVerificationData},
45    QrVerificationState, ScanError,
46};
47#[cfg(feature = "qrcode")]
48pub use qrcode::QrVerification;
49pub use requests::{VerificationRequest, VerificationRequestState};
50use ruma::RoomId;
51pub use sas::SasVerification;
52
53/// An enum over the different verification types the SDK supports.
54#[derive(Debug, Clone)]
55#[non_exhaustive]
56pub enum Verification {
57    /// The `m.sas.v1` verification variant.
58    SasV1(SasVerification),
59    #[cfg(feature = "qrcode")]
60    /// The `m.qr_code.*.v1` verification variant.
61    QrV1(QrVerification),
62}
63
64impl Verification {
65    /// Try to deconstruct this verification enum into a SAS verification.
66    pub fn sas(self) -> Option<SasVerification> {
67        as_variant!(self, Verification::SasV1)
68    }
69
70    /// Try to deconstruct this verification enum into a QR code verification.
71    #[cfg(feature = "qrcode")]
72    pub fn qr(self) -> Option<QrVerification> {
73        as_variant!(self, Verification::QrV1)
74    }
75
76    /// Has this verification finished.
77    pub fn is_done(&self) -> bool {
78        match self {
79            Verification::SasV1(s) => s.is_done(),
80            #[cfg(feature = "qrcode")]
81            Verification::QrV1(qr) => qr.is_done(),
82        }
83    }
84
85    /// Has the verification been cancelled.
86    pub fn is_cancelled(&self) -> bool {
87        match self {
88            Verification::SasV1(s) => s.is_cancelled(),
89            #[cfg(feature = "qrcode")]
90            Verification::QrV1(qr) => qr.is_cancelled(),
91        }
92    }
93
94    /// Get info about the cancellation if the verification flow has been
95    /// cancelled.
96    pub fn cancel_info(&self) -> Option<CancelInfo> {
97        match self {
98            Verification::SasV1(s) => s.cancel_info(),
99            #[cfg(feature = "qrcode")]
100            Verification::QrV1(q) => q.cancel_info(),
101        }
102    }
103
104    /// Get our own user id.
105    pub fn own_user_id(&self) -> &ruma::UserId {
106        match self {
107            Verification::SasV1(v) => v.own_user_id(),
108            #[cfg(feature = "qrcode")]
109            Verification::QrV1(v) => v.own_user_id(),
110        }
111    }
112
113    /// Get the user id of the other user participating in this verification
114    /// flow.
115    pub fn other_user_id(&self) -> &ruma::UserId {
116        match self {
117            Verification::SasV1(v) => v.inner.other_user_id(),
118            #[cfg(feature = "qrcode")]
119            Verification::QrV1(v) => v.inner.other_user_id(),
120        }
121    }
122
123    /// Is this a verification that is verifying one of our own devices.
124    pub fn is_self_verification(&self) -> bool {
125        match self {
126            Verification::SasV1(v) => v.is_self_verification(),
127            #[cfg(feature = "qrcode")]
128            Verification::QrV1(v) => v.is_self_verification(),
129        }
130    }
131
132    /// Did we initiate the verification flow.
133    pub fn we_started(&self) -> bool {
134        match self {
135            Verification::SasV1(s) => s.we_started(),
136            #[cfg(feature = "qrcode")]
137            Verification::QrV1(q) => q.we_started(),
138        }
139    }
140
141    /// Get the room ID, if the verification is happening inside a room.
142    pub fn room_id(&self) -> Option<&RoomId> {
143        match self {
144            Verification::SasV1(s) => s.room_id(),
145            #[cfg(feature = "qrcode")]
146            Verification::QrV1(q) => q.room_id(),
147        }
148    }
149}
150
151impl From<SasVerification> for Verification {
152    fn from(sas: SasVerification) -> Self {
153        Self::SasV1(sas)
154    }
155}
156
157#[cfg(feature = "qrcode")]
158impl From<QrVerification> for Verification {
159    fn from(qr: QrVerification) -> Self {
160        Self::QrV1(qr)
161    }
162}