crytpo: Mark verification requests as cancelled and as done
This commit is contained in:
parent
f9fb530480
commit
0a7fb2cbc3
2 changed files with 99 additions and 4 deletions
|
@ -208,6 +208,8 @@ impl VerificationMachine {
|
|||
}
|
||||
|
||||
pub fn garbage_collect(&self) {
|
||||
self.requests.retain(|_, r| !(r.is_done() || r.is_cancelled()));
|
||||
|
||||
for request in self.verifications.garbage_collect() {
|
||||
self.verifications.add_request(request)
|
||||
}
|
||||
|
@ -286,7 +288,11 @@ impl VerificationMachine {
|
|||
|
||||
self.requests.insert(request.flow_id().as_str().to_owned(), request);
|
||||
}
|
||||
AnyVerificationContent::Cancel(_) => {
|
||||
AnyVerificationContent::Cancel(c) => {
|
||||
if let Some(verification) = self.get_request(flow_id.as_str()) {
|
||||
verification.receive_cancel(event.sender(), c);
|
||||
}
|
||||
|
||||
if let Some(sas) = self.verifications.get_sas(flow_id.as_str()) {
|
||||
// This won't produce an outgoing content
|
||||
let _ = sas.receive_any_event(event.sender(), &content);
|
||||
|
@ -368,7 +374,11 @@ impl VerificationMachine {
|
|||
}
|
||||
}
|
||||
}
|
||||
AnyVerificationContent::Done(_) => {
|
||||
AnyVerificationContent::Done(c) => {
|
||||
if let Some(verification) = self.get_request(flow_id.as_str()) {
|
||||
verification.receive_done(event.sender(), c);
|
||||
}
|
||||
|
||||
if let Some(s) = self.verifications.get_sas(flow_id.as_str()) {
|
||||
let content = s.receive_any_event(event.sender(), &content);
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ use matrix_sdk_common::{
|
|||
api::r0::to_device::DeviceIdOrAllDevices,
|
||||
events::{
|
||||
key::verification::{
|
||||
cancel::CancelCode,
|
||||
ready::{ReadyEventContent, ReadyToDeviceEventContent},
|
||||
request::RequestToDeviceEventContent,
|
||||
start::StartMethod,
|
||||
|
@ -35,9 +36,11 @@ use matrix_sdk_common::{
|
|||
use tracing::{info, warn};
|
||||
|
||||
use super::{
|
||||
event_enums::{OutgoingContent, ReadyContent, RequestContent, StartContent},
|
||||
event_enums::{
|
||||
CancelContent, DoneContent, OutgoingContent, ReadyContent, RequestContent, StartContent,
|
||||
},
|
||||
sas::content_to_request,
|
||||
FlowId, VerificationCache,
|
||||
Cancelled, FlowId, VerificationCache,
|
||||
};
|
||||
use crate::{
|
||||
olm::{PrivateCrossSigningIdentity, ReadOnlyAccount},
|
||||
|
@ -159,6 +162,17 @@ impl VerificationRequest {
|
|||
&self.flow_id
|
||||
}
|
||||
|
||||
/// Has the verification flow that was started with this request finished.
|
||||
pub fn is_done(&self) -> bool {
|
||||
matches!(&*self.inner.lock().unwrap(), InnerRequest::Done(_))
|
||||
}
|
||||
|
||||
/// Has the verification flow that was started with this request been
|
||||
/// cancelled.
|
||||
pub fn is_cancelled(&self) -> bool {
|
||||
matches!(&*self.inner.lock().unwrap(), InnerRequest::Cancelled(_))
|
||||
}
|
||||
|
||||
pub(crate) fn from_request(
|
||||
cache: VerificationCache,
|
||||
account: ReadOnlyAccount,
|
||||
|
@ -230,6 +244,20 @@ impl VerificationRequest {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn receive_done(&self, sender: &UserId, content: &DoneContent<'_>) {
|
||||
if sender == self.other_user() {
|
||||
let mut inner = self.inner.lock().unwrap().clone();
|
||||
inner.into_done(content);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn receive_cancel(&self, sender: &UserId, content: &CancelContent<'_>) {
|
||||
if sender == self.other_user() {
|
||||
let mut inner = self.inner.lock().unwrap().clone();
|
||||
inner.into_canceled(content.cancel_code());
|
||||
}
|
||||
}
|
||||
|
||||
/// Is the verification request ready to start a verification flow.
|
||||
pub fn is_ready(&self) -> bool {
|
||||
matches!(&*self.inner.lock().unwrap(), InnerRequest::Ready(_))
|
||||
|
@ -267,6 +295,8 @@ enum InnerRequest {
|
|||
Requested(RequestState<Requested>),
|
||||
Ready(RequestState<Ready>),
|
||||
Passive(RequestState<Passive>),
|
||||
Done(RequestState<Done>),
|
||||
Cancelled(RequestState<Cancelled>),
|
||||
}
|
||||
|
||||
impl InnerRequest {
|
||||
|
@ -278,6 +308,8 @@ impl InnerRequest {
|
|||
DeviceIdOrAllDevices::DeviceId(r.state.other_device_id.to_owned())
|
||||
}
|
||||
InnerRequest::Passive(_) => DeviceIdOrAllDevices::AllDevices,
|
||||
InnerRequest::Done(_) => DeviceIdOrAllDevices::AllDevices,
|
||||
InnerRequest::Cancelled(_) => DeviceIdOrAllDevices::AllDevices,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,6 +319,8 @@ impl InnerRequest {
|
|||
InnerRequest::Requested(s) => &s.other_user_id,
|
||||
InnerRequest::Ready(s) => &s.other_user_id,
|
||||
InnerRequest::Passive(s) => &s.other_user_id,
|
||||
InnerRequest::Done(s) => &s.other_user_id,
|
||||
InnerRequest::Cancelled(s) => &s.other_user_id,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -301,6 +335,28 @@ impl InnerRequest {
|
|||
}
|
||||
}
|
||||
|
||||
fn into_done(&mut self, content: &DoneContent) {
|
||||
*self = InnerRequest::Done(match self {
|
||||
InnerRequest::Created(s) => s.clone().into_done(content),
|
||||
InnerRequest::Requested(s) => s.clone().into_done(content),
|
||||
InnerRequest::Ready(s) => s.clone().into_done(content),
|
||||
InnerRequest::Passive(s) => s.clone().into_done(content),
|
||||
InnerRequest::Done(s) => s.clone().into_done(content),
|
||||
InnerRequest::Cancelled(_) => return,
|
||||
})
|
||||
}
|
||||
|
||||
fn into_canceled(&mut self, cancel_code: &CancelCode) {
|
||||
*self = InnerRequest::Cancelled(match self {
|
||||
InnerRequest::Created(s) => s.clone().into_canceled(cancel_code),
|
||||
InnerRequest::Requested(s) => s.clone().into_canceled(cancel_code),
|
||||
InnerRequest::Ready(s) => s.clone().into_canceled(cancel_code),
|
||||
InnerRequest::Passive(s) => s.clone().into_canceled(cancel_code),
|
||||
InnerRequest::Done(_) => return,
|
||||
InnerRequest::Cancelled(_) => return,
|
||||
})
|
||||
}
|
||||
|
||||
fn to_started_sas(
|
||||
&self,
|
||||
content: &StartContent,
|
||||
|
@ -330,6 +386,32 @@ struct RequestState<S: Clone> {
|
|||
state: S,
|
||||
}
|
||||
|
||||
impl<S: Clone> RequestState<S> {
|
||||
fn into_done(self, _: &DoneContent) -> RequestState<Done> {
|
||||
RequestState::<Done> {
|
||||
account: self.account,
|
||||
private_cross_signing_identity: self.private_cross_signing_identity,
|
||||
verification_cache: self.verification_cache,
|
||||
store: self.store,
|
||||
flow_id: self.flow_id,
|
||||
other_user_id: self.other_user_id,
|
||||
state: Done {},
|
||||
}
|
||||
}
|
||||
|
||||
fn into_canceled(self, cancel_code: &CancelCode) -> RequestState<Cancelled> {
|
||||
RequestState::<Cancelled> {
|
||||
account: self.account,
|
||||
private_cross_signing_identity: self.private_cross_signing_identity,
|
||||
verification_cache: self.verification_cache,
|
||||
store: self.store,
|
||||
flow_id: self.flow_id,
|
||||
other_user_id: self.other_user_id,
|
||||
state: Cancelled::new(cancel_code.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RequestState<Created> {
|
||||
fn new(
|
||||
account: ReadOnlyAccount,
|
||||
|
@ -587,6 +669,9 @@ struct Passive {
|
|||
pub flow_id: FlowId,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Done {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::convert::TryFrom;
|
||||
|
|
Loading…
Reference in a new issue