@@ -10,7 +10,7 @@ use aide::{NoApi, OperationIo, transform::TransformOperation};
1010use axum:: { Json , extract:: State , response:: IntoResponse } ;
1111use hyper:: StatusCode ;
1212use mas_axum_utils:: record_error;
13- use mas_matrix:: HomeserverConnection ;
13+ use mas_matrix:: { HomeserverConnection , ProvisionRequest } ;
1414use mas_storage:: {
1515 BoxRng ,
1616 queue:: { ProvisionUserJob , QueueJobRepositoryExt as _} ,
@@ -106,6 +106,10 @@ pub struct Request {
106106 /// tokens (like with admin access) for them
107107 #[ serde( default ) ]
108108 skip_homeserver_check : bool ,
109+
110+ /// Delay the response until the user has been created on the homeserver.
111+ #[ serde( default ) ]
112+ add_synchronously : bool ,
109113}
110114
111115pub fn doc ( operation : TransformOperation ) -> TransformOperation {
@@ -168,9 +172,19 @@ pub async fn handler(
168172
169173 let user = repo. user ( ) . add ( & mut rng, & clock, params. username ) . await ?;
170174
171- repo. queue_job ( )
172- . schedule_job ( & mut rng, & clock, ProvisionUserJob :: new ( & user) )
173- . await ?;
175+ if params. add_synchronously {
176+ homeserver
177+ . provision_user ( & ProvisionRequest :: new (
178+ homeserver. mxid ( & user. username ) ,
179+ & user. sub ,
180+ ) )
181+ . await
182+ . map_err ( RouteError :: Homeserver ) ?;
183+ } else {
184+ repo. queue_job ( )
185+ . schedule_job ( & mut rng, & clock, ProvisionUserJob :: new ( & user) )
186+ . await ?;
187+ }
174188
175189 repo. save ( ) . await ?;
176190
@@ -183,6 +197,7 @@ pub async fn handler(
183197#[ cfg( test) ]
184198mod tests {
185199 use hyper:: { Request , StatusCode } ;
200+ use mas_matrix:: HomeserverConnection ;
186201 use mas_storage:: { RepositoryAccess , user:: UserRepository } ;
187202 use sqlx:: PgPool ;
188203
@@ -220,6 +235,28 @@ mod tests {
220235 assert_eq ! ( user. username, "alice" ) ;
221236 }
222237
238+ #[ sqlx:: test( migrator = "mas_storage_pg::MIGRATOR" ) ]
239+ async fn test_add_user_synchronously ( pool : PgPool ) {
240+ setup ( ) ;
241+ let mut state = TestState :: from_pool ( pool) . await . unwrap ( ) ;
242+ let token = state. token_with_scope ( "urn:mas:admin" ) . await ;
243+
244+ let request = Request :: post ( "/api/admin/v1/users" )
245+ . bearer ( & token)
246+ . json ( serde_json:: json!( {
247+ "username" : "alice" ,
248+ "add_synchronously" : true ,
249+ } ) ) ;
250+
251+ let response = state. request ( request) . await ;
252+ response. assert_status ( StatusCode :: CREATED ) ;
253+
254+ // Check that the user was created on the homeserver
255+ let mxid = state. homeserver_connection . mxid ( "alice" ) ;
256+ let result = state. homeserver_connection . query_user ( & mxid) . await ;
257+ assert ! ( result. is_ok( ) ) ;
258+ }
259+
223260 #[ sqlx:: test( migrator = "mas_storage_pg::MIGRATOR" ) ]
224261 async fn test_add_user_invalid_username ( pool : PgPool ) {
225262 setup ( ) ;
0 commit comments