@@ -7,10 +7,11 @@ use matrix_sdk::{
7
7
verification:: { SasState , SasVerification , VerificationRequest , VerificationRequestState } ,
8
8
Encryption ,
9
9
} ,
10
- ruma:: events:: { key:: verification:: VerificationMethod , AnyToDeviceEvent } ,
10
+ ruma:: events:: key:: verification:: VerificationMethod ,
11
+ Account ,
11
12
} ;
12
13
use ruma:: UserId ;
13
- use tracing:: { error, info } ;
14
+ use tracing:: error;
14
15
15
16
use super :: RUNTIME ;
16
17
use crate :: { error:: ClientError , utils:: Timestamp } ;
@@ -42,9 +43,10 @@ pub enum SessionVerificationData {
42
43
#[ derive( Debug , uniffi:: Record ) ]
43
44
pub struct SessionVerificationRequestDetails {
44
45
sender_id : String ,
46
+ sender_display_name : Option < String > ,
45
47
flow_id : String ,
46
48
device_id : String ,
47
- display_name : Option < String > ,
49
+ device_display_name : Option < String > ,
48
50
/// First time this device was seen in milliseconds since epoch.
49
51
first_seen_timestamp : Timestamp ,
50
52
}
@@ -66,6 +68,7 @@ pub type Delegate = Arc<RwLock<Option<Box<dyn SessionVerificationControllerDeleg
66
68
pub struct SessionVerificationController {
67
69
encryption : Encryption ,
68
70
user_identity : UserIdentity ,
71
+ account : Account ,
69
72
delegate : Delegate ,
70
73
verification_request : Arc < RwLock < Option < VerificationRequest > > > ,
71
74
sas_verification : Arc < RwLock < Option < SasVerification > > > ,
@@ -94,15 +97,7 @@ impl SessionVerificationController {
94
97
. await
95
98
. ok_or ( ClientError :: new ( "Unknown session verification request" ) ) ?;
96
99
97
- * self . verification_request . write ( ) . unwrap ( ) = Some ( verification_request. clone ( ) ) ;
98
-
99
- RUNTIME . spawn ( Self :: listen_to_verification_request_changes (
100
- verification_request,
101
- self . sas_verification . clone ( ) ,
102
- self . delegate . clone ( ) ,
103
- ) ) ;
104
-
105
- Ok ( ( ) )
100
+ self . set_ongoing_verification_request ( verification_request)
106
101
}
107
102
108
103
/// Accept the previously acknowledged verification request
@@ -118,23 +113,39 @@ impl SessionVerificationController {
118
113
}
119
114
120
115
/// Request verification for the current device
121
- pub async fn request_verification ( & self ) -> Result < ( ) , ClientError > {
116
+ pub async fn request_device_verification ( & self ) -> Result < ( ) , ClientError > {
122
117
let methods = vec ! [ VerificationMethod :: SasV1 ] ;
123
118
let verification_request = self
124
119
. user_identity
125
120
. request_verification_with_methods ( methods)
126
121
. await
127
122
. map_err ( anyhow:: Error :: from) ?;
128
123
129
- * self . verification_request . write ( ) . unwrap ( ) = Some ( verification_request. clone ( ) ) ;
124
+ self . set_ongoing_verification_request ( verification_request)
125
+ }
130
126
131
- RUNTIME . spawn ( Self :: listen_to_verification_request_changes (
132
- verification_request,
133
- self . sas_verification . clone ( ) ,
134
- self . delegate . clone ( ) ,
135
- ) ) ;
127
+ /// Request verification for the given user
128
+ pub async fn request_user_verification ( & self , user_id : String ) -> Result < ( ) , ClientError > {
129
+ let user_id = UserId :: parse ( user_id) ?;
136
130
137
- Ok ( ( ) )
131
+ let user_identity = self
132
+ . encryption
133
+ . get_user_identity ( & user_id)
134
+ . await ?
135
+ . ok_or ( ClientError :: new ( "Unknown user identity" ) ) ?;
136
+
137
+ if user_identity. is_verified ( ) {
138
+ return Err ( ClientError :: new ( "User is already verified" ) ) ;
139
+ }
140
+
141
+ let methods = vec ! [ VerificationMethod :: SasV1 ] ;
142
+
143
+ let verification_request = user_identity
144
+ . request_verification_with_methods ( methods)
145
+ . await
146
+ . map_err ( anyhow:: Error :: from) ?;
147
+
148
+ self . set_ongoing_verification_request ( verification_request)
138
149
}
139
150
140
151
/// Transition the current verification request into a SAS verification
@@ -202,50 +213,79 @@ impl SessionVerificationController {
202
213
}
203
214
204
215
impl SessionVerificationController {
205
- pub ( crate ) fn new ( encryption : Encryption , user_identity : UserIdentity ) -> Self {
216
+ pub ( crate ) fn new (
217
+ encryption : Encryption ,
218
+ user_identity : UserIdentity ,
219
+ account : Account ,
220
+ ) -> Self {
206
221
SessionVerificationController {
207
222
encryption,
208
223
user_identity,
224
+ account,
209
225
delegate : Arc :: new ( RwLock :: new ( None ) ) ,
210
226
verification_request : Arc :: new ( RwLock :: new ( None ) ) ,
211
227
sas_verification : Arc :: new ( RwLock :: new ( None ) ) ,
212
228
}
213
229
}
214
230
215
- pub ( crate ) async fn process_to_device_message ( & self , event : AnyToDeviceEvent ) {
216
- if let AnyToDeviceEvent :: KeyVerificationRequest ( event ) = event {
217
- info ! ( "Received verification request: {:}" , event . sender ) ;
218
-
219
- let Some ( request ) = self
220
- . encryption
221
- . get_verification_request ( & event . sender , & event . content . transaction_id )
222
- . await
223
- else {
224
- error ! ( "Failed retrieving verification request" ) ;
225
- return ;
226
- } ;
227
-
228
- if ! request. is_self_verification ( ) {
229
- info ! ( "Received non-self verification request. Ignoring ." ) ;
230
- return ;
231
- }
231
+ /// Ask the controller to process an incoming request based on the sender
232
+ /// and flow identifier. It will fetch the request, verify that it's in the
233
+ /// correct state and then and notify the delegate.
234
+ pub ( crate ) async fn process_incoming_verification_request (
235
+ & self ,
236
+ sender : & UserId ,
237
+ flow_id : impl AsRef < str > ,
238
+ ) {
239
+ let Some ( request ) = self . encryption . get_verification_request ( sender , flow_id ) . await else {
240
+ error ! ( "Failed retrieving verification request" ) ;
241
+ return ;
242
+ } ;
243
+
244
+ let VerificationRequestState :: Requested { other_device_data , .. } = request. state ( ) else {
245
+ error ! ( "Received verification request event but the request is in the wrong state ." ) ;
246
+ return ;
247
+ } ;
232
248
233
- let VerificationRequestState :: Requested { other_device_data, .. } = request. state ( )
234
- else {
235
- error ! ( "Received key verification event but the request is in the wrong state." ) ;
236
- return ;
237
- } ;
238
-
239
- if let Some ( delegate) = & * self . delegate . read ( ) . unwrap ( ) {
240
- delegate. did_receive_verification_request ( SessionVerificationRequestDetails {
241
- sender_id : request. other_user_id ( ) . into ( ) ,
242
- flow_id : request. flow_id ( ) . into ( ) ,
243
- device_id : other_device_data. device_id ( ) . into ( ) ,
244
- display_name : other_device_data. display_name ( ) . map ( str:: to_string) ,
245
- first_seen_timestamp : other_device_data. first_time_seen_ts ( ) . into ( ) ,
246
- } ) ;
249
+ let Ok ( user_profile) = self . account . fetch_user_profile_of ( sender) . await else {
250
+ error ! ( "Failed fetching user profile for verification request" ) ;
251
+ return ;
252
+ } ;
253
+
254
+ if let Some ( delegate) = & * self . delegate . read ( ) . unwrap ( ) {
255
+ delegate. did_receive_verification_request ( SessionVerificationRequestDetails {
256
+ sender_id : request. other_user_id ( ) . into ( ) ,
257
+ sender_display_name : user_profile. displayname ,
258
+ flow_id : request. flow_id ( ) . into ( ) ,
259
+ device_id : other_device_data. device_id ( ) . into ( ) ,
260
+ device_display_name : other_device_data. display_name ( ) . map ( str:: to_string) ,
261
+ first_seen_timestamp : other_device_data. first_time_seen_ts ( ) . into ( ) ,
262
+ } ) ;
263
+ }
264
+ }
265
+
266
+ fn set_ongoing_verification_request (
267
+ & self ,
268
+ verification_request : VerificationRequest ,
269
+ ) -> Result < ( ) , ClientError > {
270
+ if let Some ( ongoing_verification_request) =
271
+ self . verification_request . read ( ) . unwrap ( ) . clone ( )
272
+ {
273
+ if !ongoing_verification_request. is_done ( )
274
+ && !ongoing_verification_request. is_cancelled ( )
275
+ {
276
+ return Err ( ClientError :: new ( "There is another verification flow ongoing." ) ) ;
247
277
}
248
278
}
279
+
280
+ * self . verification_request . write ( ) . unwrap ( ) = Some ( verification_request. clone ( ) ) ;
281
+
282
+ RUNTIME . spawn ( Self :: listen_to_verification_request_changes (
283
+ verification_request,
284
+ self . sas_verification . clone ( ) ,
285
+ self . delegate . clone ( ) ,
286
+ ) ) ;
287
+
288
+ Ok ( ( ) )
249
289
}
250
290
251
291
async fn listen_to_verification_request_changes (
0 commit comments