libsignal_service/
session_store.rs

1use async_trait::async_trait;
2use libsignal_protocol::{
3    ProtocolAddress, ServiceId, SessionStore, SignalProtocolError,
4};
5
6use crate::push_service::DEFAULT_DEVICE_ID;
7
8/// This is additional functions required to handle
9/// session deletion. It might be a candidate for inclusion into
10/// the bigger `SessionStore` trait.
11#[async_trait(?Send)]
12pub trait SessionStoreExt: SessionStore {
13    /// Get the IDs of all known sub devices with active sessions for a recipient.
14    ///
15    /// This should return every device except for the main device [DEFAULT_DEVICE_ID].
16    async fn get_sub_device_sessions(
17        &self,
18        name: &ServiceId,
19    ) -> Result<Vec<u32>, SignalProtocolError>;
20
21    /// Remove a session record for a recipient ID + device ID tuple.
22    async fn delete_session(
23        &self,
24        address: &ProtocolAddress,
25    ) -> Result<(), SignalProtocolError>;
26
27    /// Remove the session records corresponding to all devices of a recipient
28    /// ID.
29    ///
30    /// Returns the number of deleted sessions.
31    async fn delete_all_sessions(
32        &self,
33        address: &ServiceId,
34    ) -> Result<usize, SignalProtocolError>;
35
36    /// Remove a session record for a recipient ID + device ID tuple.
37    async fn delete_service_addr_device_session(
38        &self,
39        address: &ProtocolAddress,
40    ) -> Result<usize, SignalProtocolError> {
41        let mut count = 0;
42        match self.delete_session(address).await {
43            Ok(()) => {
44                count += 1;
45            },
46            Err(SignalProtocolError::SessionNotFound(_)) => (),
47            Err(e) => return Err(e),
48        }
49
50        Ok(count)
51    }
52
53    async fn compute_safety_number(
54        &self,
55        local_address: &ServiceId,
56        address: &ServiceId,
57    ) -> Result<String, SignalProtocolError>
58    where
59        Self: Sized + libsignal_protocol::IdentityKeyStore,
60    {
61        let addr = crate::cipher::get_preferred_protocol_address(
62            self,
63            address,
64            DEFAULT_DEVICE_ID.into(),
65        )
66        .await?;
67        let ident = self
68            .get_identity(&addr)
69            .await?
70            .ok_or(SignalProtocolError::UntrustedIdentity(addr))?;
71        let local = self
72            .get_identity_key_pair()
73            .await
74            .expect("valid local identity");
75        let fp = libsignal_protocol::Fingerprint::new(
76            2,
77            5200,
78            local_address.raw_uuid().as_bytes(),
79            local.identity_key(),
80            address.raw_uuid().as_bytes(),
81            &ident,
82        )?;
83        fp.display_string()
84    }
85}