matrix-sdk: Rework the public API for answering verifications
This commit is contained in:
parent
baee5b2d11
commit
3cf843d24f
11 changed files with 426 additions and 162 deletions
|
@ -11,11 +11,12 @@ use matrix_sdk::{
|
|||
self,
|
||||
events::{room::message::MessageType, AnySyncMessageEvent, AnySyncRoomEvent, AnyToDeviceEvent},
|
||||
identifiers::UserId,
|
||||
Client, LoopCtrl, Sas, SyncSettings,
|
||||
verification::{SasVerification, Verification},
|
||||
Client, LoopCtrl, SyncSettings,
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
async fn wait_for_confirmation(client: Client, sas: Sas) {
|
||||
async fn wait_for_confirmation(client: Client, sas: SasVerification) {
|
||||
println!("Does the emoji match: {:?}", sas.emoji());
|
||||
|
||||
let mut input = String::new();
|
||||
|
@ -34,7 +35,7 @@ async fn wait_for_confirmation(client: Client, sas: Sas) {
|
|||
}
|
||||
}
|
||||
|
||||
fn print_result(sas: &Sas) {
|
||||
fn print_result(sas: &SasVerification) {
|
||||
let device = sas.other_device();
|
||||
|
||||
println!(
|
||||
|
@ -80,37 +81,35 @@ async fn login(
|
|||
for event in response.to_device.events.iter().filter_map(|e| e.deserialize().ok()) {
|
||||
match event {
|
||||
AnyToDeviceEvent::KeyVerificationStart(e) => {
|
||||
let sas = client
|
||||
.get_verification(&e.sender, &e.content.transaction_id)
|
||||
.await
|
||||
.expect("Sas object wasn't created");
|
||||
println!(
|
||||
"Starting verification with {} {}",
|
||||
&sas.other_device().user_id(),
|
||||
&sas.other_device().device_id()
|
||||
);
|
||||
print_devices(&e.sender, client).await;
|
||||
sas.accept().await.unwrap();
|
||||
if let Some(Verification::SasV1(sas)) =
|
||||
client.get_verification(&e.sender, &e.content.transaction_id).await
|
||||
{
|
||||
println!(
|
||||
"Starting verification with {} {}",
|
||||
&sas.other_device().user_id(),
|
||||
&sas.other_device().device_id()
|
||||
);
|
||||
print_devices(&e.sender, client).await;
|
||||
sas.accept().await.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
AnyToDeviceEvent::KeyVerificationKey(e) => {
|
||||
let sas = client
|
||||
.get_verification(&e.sender, &e.content.transaction_id)
|
||||
.await
|
||||
.expect("Sas object wasn't created");
|
||||
|
||||
tokio::spawn(wait_for_confirmation((*client).clone(), sas));
|
||||
if let Some(Verification::SasV1(sas)) =
|
||||
client.get_verification(&e.sender, &e.content.transaction_id).await
|
||||
{
|
||||
tokio::spawn(wait_for_confirmation((*client).clone(), sas));
|
||||
}
|
||||
}
|
||||
|
||||
AnyToDeviceEvent::KeyVerificationMac(e) => {
|
||||
let sas = client
|
||||
.get_verification(&e.sender, &e.content.transaction_id)
|
||||
.await
|
||||
.expect("Sas object wasn't created");
|
||||
|
||||
if sas.is_done() {
|
||||
print_result(&sas);
|
||||
print_devices(&e.sender, client).await;
|
||||
if let Some(Verification::SasV1(sas)) =
|
||||
client.get_verification(&e.sender, &e.content.transaction_id).await
|
||||
{
|
||||
if sas.is_done() {
|
||||
print_result(&sas);
|
||||
print_devices(&e.sender, client).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,28 +139,28 @@ async fn login(
|
|||
}
|
||||
}
|
||||
AnySyncMessageEvent::KeyVerificationKey(e) => {
|
||||
let sas = client
|
||||
if let Some(Verification::SasV1(sas)) = client
|
||||
.get_verification(
|
||||
&e.sender,
|
||||
e.content.relation.event_id.as_str(),
|
||||
)
|
||||
.await
|
||||
.expect("Sas object wasn't created");
|
||||
|
||||
tokio::spawn(wait_for_confirmation((*client).clone(), sas));
|
||||
{
|
||||
tokio::spawn(wait_for_confirmation((*client).clone(), sas));
|
||||
}
|
||||
}
|
||||
AnySyncMessageEvent::KeyVerificationMac(e) => {
|
||||
let sas = client
|
||||
if let Some(Verification::SasV1(sas)) = client
|
||||
.get_verification(
|
||||
&e.sender,
|
||||
e.content.relation.event_id.as_str(),
|
||||
)
|
||||
.await
|
||||
.expect("Sas object wasn't created");
|
||||
|
||||
if sas.is_done() {
|
||||
print_result(&sas);
|
||||
print_devices(&e.sender, client).await;
|
||||
{
|
||||
if sas.is_done() {
|
||||
print_result(&sas);
|
||||
print_devices(&e.sender, client).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
|
|
|
@ -126,8 +126,7 @@ use ruma::{
|
|||
#[cfg(feature = "encryption")]
|
||||
use crate::{
|
||||
device::{Device, UserDevices},
|
||||
sas::Sas,
|
||||
verification_request::VerificationRequest,
|
||||
verification::{QrVerification, SasVerification, Verification, VerificationRequest},
|
||||
};
|
||||
use crate::{
|
||||
error::HttpError,
|
||||
|
@ -2182,14 +2181,19 @@ impl Client {
|
|||
Ok(response)
|
||||
}
|
||||
|
||||
/// Get a `Sas` verification object with the given flow id.
|
||||
/// Get a verification object with the given flow id.
|
||||
#[cfg(feature = "encryption")]
|
||||
#[cfg_attr(feature = "docs", doc(cfg(encryption)))]
|
||||
pub async fn get_verification(&self, user_id: &UserId, flow_id: &str) -> Option<Sas> {
|
||||
self.base_client
|
||||
.get_verification(user_id, flow_id)
|
||||
.await
|
||||
.map(|sas| Sas { inner: sas, client: self.clone() })
|
||||
pub async fn get_verification(&self, user_id: &UserId, flow_id: &str) -> Option<Verification> {
|
||||
let olm = self.base_client.olm_machine().await?;
|
||||
olm.get_verification(user_id, flow_id).map(|v| match v {
|
||||
matrix_sdk_base::crypto::Verification::SasV1(s) => {
|
||||
SasVerification { inner: s, client: self.clone() }.into()
|
||||
}
|
||||
matrix_sdk_base::crypto::Verification::QrV1(qr) => {
|
||||
QrVerification { inner: qr, client: self.clone() }.into()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Get a `VerificationRequest` object for the given user with the given
|
||||
|
@ -2697,6 +2701,22 @@ impl Client {
|
|||
let request = whoami::Request::new();
|
||||
self.send(request, None).await
|
||||
}
|
||||
|
||||
pub(crate) async fn send_verification_request(
|
||||
&self,
|
||||
request: matrix_sdk_base::crypto::OutgoingVerificationRequest,
|
||||
) -> Result<()> {
|
||||
match request {
|
||||
matrix_sdk_base::crypto::OutgoingVerificationRequest::ToDevice(t) => {
|
||||
self.send_to_device(&t).await?;
|
||||
}
|
||||
matrix_sdk_base::crypto::OutgoingVerificationRequest::InRoom(r) => {
|
||||
self.room_send_helper(&r).await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -20,7 +20,7 @@ use matrix_sdk_base::crypto::{
|
|||
};
|
||||
use ruma::{DeviceId, DeviceIdBox};
|
||||
|
||||
use crate::{error::Result, Client, Sas};
|
||||
use crate::{error::Result, verification::SasVerification, Client};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// A device represents a E2EE capable client of an user.
|
||||
|
@ -62,11 +62,11 @@ impl Device {
|
|||
/// let verification = device.start_verification().await.unwrap();
|
||||
/// # });
|
||||
/// ```
|
||||
pub async fn start_verification(&self) -> Result<Sas> {
|
||||
pub async fn start_verification(&self) -> Result<SasVerification> {
|
||||
let (sas, request) = self.inner.start_verification().await?;
|
||||
self.client.send_to_device(&request).await?;
|
||||
|
||||
Ok(Sas { inner: sas, client: self.client.clone() })
|
||||
Ok(SasVerification { inner: sas, client: self.client.clone() })
|
||||
}
|
||||
|
||||
/// Is the device trusted.
|
||||
|
|
|
@ -115,9 +115,7 @@ mod room_member;
|
|||
#[cfg(feature = "encryption")]
|
||||
mod device;
|
||||
#[cfg(feature = "encryption")]
|
||||
mod sas;
|
||||
#[cfg(feature = "encryption")]
|
||||
mod verification_request;
|
||||
pub mod verification;
|
||||
|
||||
pub use client::{Client, ClientConfig, LoopCtrl, RequestConfig, SyncSettings};
|
||||
#[cfg(feature = "encryption")]
|
||||
|
@ -127,12 +125,5 @@ pub use error::{Error, HttpError, Result};
|
|||
pub use event_handler::{CustomEvent, EventHandler};
|
||||
pub use http_client::HttpSend;
|
||||
pub use room_member::RoomMember;
|
||||
#[cfg(feature = "encryption")]
|
||||
#[cfg_attr(feature = "docs", doc(cfg(encryption)))]
|
||||
pub use sas::Sas;
|
||||
#[cfg(feature = "encryption")]
|
||||
#[cfg_attr(feature = "docs", doc(cfg(encryption)))]
|
||||
pub use verification_request::VerificationRequest;
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(crate) const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
|
120
matrix_sdk/src/verification/mod.rs
Normal file
120
matrix_sdk/src/verification/mod.rs
Normal file
|
@ -0,0 +1,120 @@
|
|||
// Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//! Interactive verification for E2EE capable users and devices in Matrix.
|
||||
//!
|
||||
//! The SDK supports interactive verification of devices and users, this module
|
||||
//! contains types that model and support different verification flows.
|
||||
//!
|
||||
//! A verification flow usually starts its life as a [VerificationRequest], the
|
||||
//! request can then be accepted, or it needs to be accepted by the other side
|
||||
//! of the verification flow.
|
||||
//!
|
||||
//! Once both sides have agreed to pereform the verification, and the
|
||||
//! [VerificationRequest::is_ready()] method returns true, the verification can
|
||||
//! transition into one of the supported verification flows:
|
||||
//!
|
||||
//! * [SasVerification] - Interactive verification using a short authentication
|
||||
//! string.
|
||||
//! * [QrVerification] - Interactive verification using QR codes.
|
||||
|
||||
mod qrcode;
|
||||
mod requests;
|
||||
mod sas;
|
||||
|
||||
pub use qrcode::QrVerification;
|
||||
pub use requests::VerificationRequest;
|
||||
pub use sas::SasVerification;
|
||||
|
||||
/// An enum over the different verification types the SDK supports.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Verification {
|
||||
/// The `m.sas.v1` verification variant.
|
||||
SasV1(SasVerification),
|
||||
/// The `m.qr_code.*.v1` verification variant.
|
||||
QrV1(QrVerification),
|
||||
}
|
||||
|
||||
impl Verification {
|
||||
/// Try to deconstruct this verification enum into a SAS verification.
|
||||
pub fn sas(self) -> Option<SasVerification> {
|
||||
if let Verification::SasV1(sas) = self {
|
||||
Some(sas)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Try to deconstruct this verification enum into a QR code verification.
|
||||
pub fn qr(self) -> Option<QrVerification> {
|
||||
if let Verification::QrV1(qr) = self {
|
||||
Some(qr)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Has this verification finished.
|
||||
pub fn is_done(&self) -> bool {
|
||||
match self {
|
||||
Verification::SasV1(s) => s.is_done(),
|
||||
Verification::QrV1(qr) => qr.is_done(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Has the verification been cancelled.
|
||||
pub fn is_cancelled(&self) -> bool {
|
||||
match self {
|
||||
Verification::SasV1(s) => s.is_cancelled(),
|
||||
Verification::QrV1(qr) => qr.is_cancelled(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get our own user id.
|
||||
pub fn own_user_id(&self) -> &ruma::UserId {
|
||||
match self {
|
||||
Verification::SasV1(v) => v.own_user_id(),
|
||||
Verification::QrV1(v) => v.own_user_id(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the user id of the other user participating in this verification
|
||||
/// flow.
|
||||
pub fn other_user_id(&self) -> &ruma::UserId {
|
||||
match self {
|
||||
Verification::SasV1(v) => v.inner.other_user_id(),
|
||||
Verification::QrV1(v) => v.inner.other_user_id(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Is this a verification that is veryfying one of our own devices.
|
||||
pub fn is_self_verification(&self) -> bool {
|
||||
match self {
|
||||
Verification::SasV1(v) => v.is_self_verification(),
|
||||
Verification::QrV1(v) => v.is_self_verification(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SasVerification> for Verification {
|
||||
fn from(sas: SasVerification) -> Self {
|
||||
Self::SasV1(sas)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<QrVerification> for Verification {
|
||||
fn from(qr: QrVerification) -> Self {
|
||||
Self::QrV1(qr)
|
||||
}
|
||||
}
|
87
matrix_sdk/src/verification/qrcode.rs
Normal file
87
matrix_sdk/src/verification/qrcode.rs
Normal file
|
@ -0,0 +1,87 @@
|
|||
// Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use matrix_sdk_base::crypto::{
|
||||
matrix_qrcode::{qrcode::QrCode, EncodingError},
|
||||
QrVerification as BaseQrVerification,
|
||||
};
|
||||
use ruma::UserId;
|
||||
|
||||
use crate::{Client, Result};
|
||||
|
||||
/// An object controlling QR code style key verification flows.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct QrVerification {
|
||||
pub(crate) inner: BaseQrVerification,
|
||||
pub(crate) client: Client,
|
||||
}
|
||||
|
||||
impl QrVerification {
|
||||
/// Get our own user id.
|
||||
pub fn own_user_id(&self) -> &UserId {
|
||||
self.inner.user_id()
|
||||
}
|
||||
|
||||
/// Is this a verification that is veryfying one of our own devices.
|
||||
pub fn is_self_verification(&self) -> bool {
|
||||
self.inner.is_self_verification()
|
||||
}
|
||||
|
||||
/// Has this verification finished.
|
||||
pub fn is_done(&self) -> bool {
|
||||
self.inner.is_done()
|
||||
}
|
||||
|
||||
/// Has the verification been cancelled.
|
||||
pub fn is_cancelled(&self) -> bool {
|
||||
self.inner.is_cancelled()
|
||||
}
|
||||
|
||||
/// Generate a QR code object that is representing this verification flow.
|
||||
///
|
||||
/// The `QrCode` can then be rendered as an image or as an unicode string.
|
||||
///
|
||||
/// The [`to_bytes()`](#method.to_bytes) method can be used to instead
|
||||
/// output the raw bytes that should be encoded as a QR code.
|
||||
pub fn to_qr_code(&self) -> std::result::Result<QrCode, EncodingError> {
|
||||
self.inner.to_qr_code()
|
||||
}
|
||||
|
||||
/// Generate a the raw bytes that should be encoded as a QR code is
|
||||
/// representing this verification flow.
|
||||
///
|
||||
/// The [`to_qr_code()`](#method.to_qr_code) method can be used to instead
|
||||
/// output a `QrCode` object that can be rendered.
|
||||
pub fn to_bytes(&self) -> std::result::Result<Vec<u8>, EncodingError> {
|
||||
self.inner.to_bytes()
|
||||
}
|
||||
|
||||
/// Confirm that the other side has scanned our QR code.
|
||||
pub async fn confirm(&self) -> Result<()> {
|
||||
if let Some(request) = self.inner.confirm_scanning() {
|
||||
self.client.send_verification_request(request).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Abort the verification flow and notify the other side that we did so.
|
||||
pub async fn cancel(&self) -> Result<()> {
|
||||
if let Some(request) = self.inner.cancel() {
|
||||
self.client.send_verification_request(request).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
132
matrix_sdk/src/verification/requests.rs
Normal file
132
matrix_sdk/src/verification/requests.rs
Normal file
|
@ -0,0 +1,132 @@
|
|||
// Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use matrix_sdk_base::crypto::VerificationRequest as BaseVerificationRequest;
|
||||
use ruma::events::key::verification::VerificationMethod;
|
||||
|
||||
use super::{QrVerification, SasVerification};
|
||||
use crate::{Client, Result};
|
||||
|
||||
/// An object controlling the interactive verification flow.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct VerificationRequest {
|
||||
pub(crate) inner: BaseVerificationRequest,
|
||||
pub(crate) client: Client,
|
||||
}
|
||||
|
||||
impl VerificationRequest {
|
||||
/// Has this verification finished.
|
||||
pub fn is_done(&self) -> bool {
|
||||
self.inner.is_done()
|
||||
}
|
||||
|
||||
/// Has the verification been cancelled.
|
||||
pub fn is_cancelled(&self) -> bool {
|
||||
self.inner.is_cancelled()
|
||||
}
|
||||
|
||||
/// Get our own user id.
|
||||
pub fn own_user_id(&self) -> &ruma::UserId {
|
||||
self.inner.own_user_id()
|
||||
}
|
||||
|
||||
/// Has the verification request been answered by another device.
|
||||
pub fn is_passive(&self) -> bool {
|
||||
self.inner.is_passive()
|
||||
}
|
||||
|
||||
/// Is the verification request ready to start a verification flow.
|
||||
pub fn is_ready(&self) -> bool {
|
||||
self.inner.is_ready()
|
||||
}
|
||||
|
||||
/// Get the user id of the other user participating in this verification
|
||||
/// flow.
|
||||
pub fn other_user_id(&self) -> &ruma::UserId {
|
||||
self.inner.other_user()
|
||||
}
|
||||
|
||||
/// Is this a verification that is veryfying one of our own devices.
|
||||
pub fn is_self_verification(&self) -> bool {
|
||||
self.inner.is_self_verification()
|
||||
}
|
||||
|
||||
/// Get the supported verification methods of the other side.
|
||||
///
|
||||
/// Will be present only if the other side requested the verification or if
|
||||
/// we're in the ready state.
|
||||
pub fn their_supported_methods(&self) -> Option<Vec<VerificationMethod>> {
|
||||
self.inner.their_supported_methods()
|
||||
}
|
||||
|
||||
/// Accept the verification request.
|
||||
///
|
||||
/// This method will accept the request and signal that it supports the
|
||||
/// `m.sas.v1`, the `m.qr_code.show.v1`, and `m.reciprocate.v1` method.
|
||||
///
|
||||
/// If QR code scanning should be supported or QR code showing shouldn't be
|
||||
/// supported the [`accept_with_methods()`] method should be used instead.
|
||||
///
|
||||
/// [`accept_with_methods()`]: #method.accept_with_methods
|
||||
pub async fn accept(&self) -> Result<()> {
|
||||
if let Some(request) = self.inner.accept() {
|
||||
self.client.send_verification_request(request).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Accept the verification request signaling that our client supports the
|
||||
/// given verification methods.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `methods` - The methods that we should advertise as supported by us.
|
||||
pub async fn accept_with_methods(&self, methods: Vec<VerificationMethod>) -> Result<()> {
|
||||
if let Some(request) = self.inner.accept_with_methods(methods) {
|
||||
self.client.send_verification_request(request).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Generate a QR code
|
||||
pub async fn generate_qr_code(&self) -> Result<Option<QrVerification>> {
|
||||
Ok(self
|
||||
.inner
|
||||
.generate_qr_code()
|
||||
.await?
|
||||
.map(|qr| QrVerification { inner: qr, client: self.client.clone() }))
|
||||
}
|
||||
|
||||
/// Transition from this verification request into a SAS verification flow.
|
||||
pub async fn start_sas(&self) -> Result<Option<SasVerification>> {
|
||||
if let Some((sas, request)) = self.inner.start_sas().await? {
|
||||
self.client.send_verification_request(request).await?;
|
||||
|
||||
Ok(Some(SasVerification { inner: sas, client: self.client.clone() }))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Cancel the verification request
|
||||
pub async fn cancel(&self) -> Result<()> {
|
||||
if let Some(request) = self.inner.cancel() {
|
||||
self.client.send_verification_request(request).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -12,21 +12,19 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use matrix_sdk_base::crypto::{
|
||||
AcceptSettings, OutgoingVerificationRequest, ReadOnlyDevice, Sas as BaseSas,
|
||||
};
|
||||
use matrix_sdk_base::crypto::{AcceptSettings, ReadOnlyDevice, Sas as BaseSas};
|
||||
use ruma::UserId;
|
||||
|
||||
use crate::{error::Result, Client};
|
||||
|
||||
/// An object controlling the interactive verification flow.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Sas {
|
||||
pub struct SasVerification {
|
||||
pub(crate) inner: BaseSas,
|
||||
pub(crate) client: Client,
|
||||
}
|
||||
|
||||
impl Sas {
|
||||
impl SasVerification {
|
||||
/// Accept the interactive verification flow.
|
||||
pub async fn accept(&self) -> Result<()> {
|
||||
self.accept_with_settings(Default::default()).await
|
||||
|
@ -45,7 +43,7 @@ impl Sas {
|
|||
/// # use futures::executor::block_on;
|
||||
/// # use url::Url;
|
||||
/// # use ruma::identifiers::user_id;
|
||||
/// use matrix_sdk::Sas;
|
||||
/// use matrix_sdk::verification::SasVerification;
|
||||
/// use matrix_sdk_base::crypto::AcceptSettings;
|
||||
/// use matrix_sdk::events::key::verification::ShortAuthenticationString;
|
||||
/// # let homeserver = Url::parse("http://example.com").unwrap();
|
||||
|
@ -56,6 +54,8 @@ impl Sas {
|
|||
/// let sas = client
|
||||
/// .get_verification(&user_id, flow_id)
|
||||
/// .await
|
||||
/// .unwrap()
|
||||
/// .sas()
|
||||
/// .unwrap();
|
||||
///
|
||||
/// let only_decimal = AcceptSettings::with_allowed_methods(
|
||||
|
@ -65,15 +65,8 @@ impl Sas {
|
|||
/// # });
|
||||
/// ```
|
||||
pub async fn accept_with_settings(&self, settings: AcceptSettings) -> Result<()> {
|
||||
if let Some(req) = self.inner.accept_with_settings(settings) {
|
||||
match req {
|
||||
OutgoingVerificationRequest::ToDevice(r) => {
|
||||
self.client.send_to_device(&r).await?;
|
||||
}
|
||||
OutgoingVerificationRequest::InRoom(r) => {
|
||||
self.client.room_send_helper(&r).await?;
|
||||
}
|
||||
}
|
||||
if let Some(request) = self.inner.accept_with_settings(settings) {
|
||||
self.client.send_verification_request(request).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -82,16 +75,8 @@ impl Sas {
|
|||
pub async fn confirm(&self) -> Result<()> {
|
||||
let (request, signature) = self.inner.confirm().await?;
|
||||
|
||||
match request {
|
||||
Some(OutgoingVerificationRequest::InRoom(r)) => {
|
||||
self.client.room_send_helper(&r).await?;
|
||||
}
|
||||
|
||||
Some(OutgoingVerificationRequest::ToDevice(r)) => {
|
||||
self.client.send_to_device(&r).await?;
|
||||
}
|
||||
|
||||
None => (),
|
||||
if let Some(request) = request {
|
||||
self.client.send_verification_request(request).await?;
|
||||
}
|
||||
|
||||
if let Some(s) = signature {
|
||||
|
@ -104,14 +89,7 @@ impl Sas {
|
|||
/// Cancel the interactive verification flow.
|
||||
pub async fn cancel(&self) -> Result<()> {
|
||||
if let Some(request) = self.inner.cancel() {
|
||||
match request {
|
||||
OutgoingVerificationRequest::ToDevice(r) => {
|
||||
self.client.send_to_device(&r).await?;
|
||||
}
|
||||
OutgoingVerificationRequest::InRoom(r) => {
|
||||
self.client.room_send_helper(&r).await?;
|
||||
}
|
||||
}
|
||||
self.client.send_verification_request(request).await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -138,6 +116,11 @@ impl Sas {
|
|||
self.inner.is_done()
|
||||
}
|
||||
|
||||
/// Are we in a state where we can show the short auth string.
|
||||
pub fn can_be_presented(&self) -> bool {
|
||||
self.inner.can_be_presented()
|
||||
}
|
||||
|
||||
/// Is the verification process canceled.
|
||||
pub fn is_cancelled(&self) -> bool {
|
||||
self.inner.is_cancelled()
|
|
@ -1,49 +0,0 @@
|
|||
// Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use matrix_sdk_base::crypto::{
|
||||
OutgoingVerificationRequest, VerificationRequest as BaseVerificationRequest,
|
||||
};
|
||||
|
||||
use crate::{Client, Result};
|
||||
|
||||
/// An object controlling the interactive verification flow.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct VerificationRequest {
|
||||
pub(crate) inner: BaseVerificationRequest,
|
||||
pub(crate) client: Client,
|
||||
}
|
||||
|
||||
impl VerificationRequest {
|
||||
/// Accept the verification request
|
||||
pub async fn accept(&self) -> Result<()> {
|
||||
if let Some(request) = self.inner.accept() {
|
||||
match request {
|
||||
OutgoingVerificationRequest::ToDevice(r) => {
|
||||
self.client.send_to_device(&r).await?;
|
||||
}
|
||||
OutgoingVerificationRequest::InRoom(r) => {
|
||||
self.client.room_send_helper(&r).await?;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Cancel the verification request
|
||||
pub async fn cancel(&self) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
}
|
|
@ -36,7 +36,7 @@ use matrix_sdk_common::{locks::Mutex, uuid::Uuid};
|
|||
use matrix_sdk_crypto::{
|
||||
store::{CryptoStore, CryptoStoreError},
|
||||
Device, EncryptionSettings, IncomingResponse, MegolmError, OlmError, OlmMachine,
|
||||
OutgoingRequest, Sas, ToDeviceRequest, UserDevices,
|
||||
OutgoingRequest, ToDeviceRequest, UserDevices,
|
||||
};
|
||||
#[cfg(feature = "encryption")]
|
||||
use ruma::{
|
||||
|
@ -1202,26 +1202,6 @@ impl BaseClient {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get a `Sas` verification object with the given flow id.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `flow_id` - The unique id that identifies a interactive verification
|
||||
/// flow. For in-room verifications this will be the event id of the
|
||||
/// *m.key.verification.request* event that started the flow, for the
|
||||
/// to-device verification flows this will be the transaction id of the
|
||||
/// *m.key.verification.start* event.
|
||||
#[cfg(feature = "encryption")]
|
||||
#[cfg_attr(feature = "docs", doc(cfg(encryption)))]
|
||||
pub async fn get_verification(&self, user_id: &UserId, flow_id: &str) -> Option<Sas> {
|
||||
self.olm
|
||||
.lock()
|
||||
.await
|
||||
.as_ref()
|
||||
.and_then(|o| o.get_verification(user_id, flow_id).map(|v| v.sas_v1()))
|
||||
.flatten()
|
||||
}
|
||||
|
||||
/// Get a specific device of a user.
|
||||
///
|
||||
/// # Arguments
|
||||
|
|
|
@ -720,6 +720,7 @@ impl SledStore {
|
|||
.map(|u| {
|
||||
u.map_err(StoreError::Sled).and_then(|(key, value)| {
|
||||
self.deserialize_event(&value)
|
||||
// TODO remove this unwrapping
|
||||
.map(|receipt| {
|
||||
(decode_key_value(&key, 3).unwrap().try_into().unwrap(), receipt)
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue