@@ -74,6 +74,7 @@ bitflags::bitflags! {
7474 const IS_SYNAPSE_ADMIN = 0b0000_0001 ;
7575 const IS_DEACTIVATED = 0b0000_0010 ;
7676 const IS_GUEST = 0b0000_0100 ;
77+ const IS_APPSERVICE = 0b0000_1000 ;
7778 }
7879}
7980
@@ -89,6 +90,10 @@ impl UserFlags {
8990 const fn is_synapse_admin ( self ) -> bool {
9091 self . contains ( UserFlags :: IS_SYNAPSE_ADMIN )
9192 }
93+
94+ const fn is_appservice ( self ) -> bool {
95+ self . contains ( UserFlags :: IS_APPSERVICE )
96+ }
9297}
9398
9499#[ derive( Debug , Clone , Copy ) ]
@@ -188,6 +193,20 @@ async fn migrate_users(
188193 if bool:: from ( user. is_guest ) {
189194 flags |= UserFlags :: IS_GUEST ;
190195 }
196+ if user. appservice_id . is_some ( ) {
197+ flags |= UserFlags :: IS_APPSERVICE ;
198+
199+ // Special case for appservice users: we don't insert them into the database
200+ // We just record the user's information in the state and continue
201+ state. users . insert (
202+ CompactString :: new ( & mas_user. username ) ,
203+ UserInfo {
204+ mas_user_id : Uuid :: nil ( ) ,
205+ flags,
206+ } ,
207+ ) ;
208+ continue ;
209+ }
191210
192211 state. users . insert (
193212 CompactString :: new ( & mas_user. username ) ,
@@ -247,15 +266,16 @@ async fn migrate_threepids(
247266 . into_extract_localpart ( synapse_user_id. clone ( ) ) ?
248267 . to_owned ( ) ;
249268 let Some ( user_infos) = state. users . get ( username. as_str ( ) ) . copied ( ) else {
250- if is_likely_appservice ( & username) {
251- continue ;
252- }
253269 return Err ( Error :: MissingUserFromDependentTable {
254270 table : "user_threepids" . to_owned ( ) ,
255271 user : synapse_user_id,
256272 } ) ;
257273 } ;
258274
275+ if user_infos. flags . is_appservice ( ) {
276+ continue ;
277+ }
278+
259279 if medium == "email" {
260280 email_buffer
261281 . write (
@@ -325,15 +345,16 @@ async fn migrate_external_ids(
325345 . into_extract_localpart ( synapse_user_id. clone ( ) ) ?
326346 . to_owned ( ) ;
327347 let Some ( user_infos) = state. users . get ( username. as_str ( ) ) . copied ( ) else {
328- if is_likely_appservice ( & username) {
329- continue ;
330- }
331348 return Err ( Error :: MissingUserFromDependentTable {
332349 table : "user_external_ids" . to_owned ( ) ,
333350 user : synapse_user_id,
334351 } ) ;
335352 } ;
336353
354+ if user_infos. flags . is_appservice ( ) {
355+ continue ;
356+ }
357+
337358 let Some ( & upstream_provider_id) = state. provider_id_mapping . get ( & auth_provider) else {
338359 return Err ( Error :: MissingAuthProviderMapping {
339360 synapse_id : auth_provider,
@@ -403,16 +424,16 @@ async fn migrate_devices(
403424 . into_extract_localpart ( synapse_user_id. clone ( ) ) ?
404425 . to_owned ( ) ;
405426 let Some ( user_infos) = state. users . get ( username. as_str ( ) ) . copied ( ) else {
406- if is_likely_appservice ( & username) {
407- continue ;
408- }
409427 return Err ( Error :: MissingUserFromDependentTable {
410428 table : "devices" . to_owned ( ) ,
411429 user : synapse_user_id,
412430 } ) ;
413431 } ;
414432
415- if user_infos. flags . is_deactivated ( ) || user_infos. flags . is_guest ( ) {
433+ if user_infos. flags . is_deactivated ( )
434+ || user_infos. flags . is_guest ( )
435+ || user_infos. flags . is_appservice ( )
436+ {
416437 continue ;
417438 }
418439
@@ -428,7 +449,9 @@ async fn migrate_devices(
428449 // As we're using a real IP type in the MAS database, it is possible
429450 // that we encounter invalid IP addresses in the Synapse database.
430451 // In that case, we should ignore them, but still log a warning.
431- let last_active_ip = ip. and_then ( |ip| {
452+ // One special case: Synapse will record '-' as IP in some cases, we don't want
453+ // to log about those
454+ let last_active_ip = ip. filter ( |ip| ip != "-" ) . and_then ( |ip| {
432455 ip. parse ( )
433456 . map_err ( |e| {
434457 tracing:: warn!(
@@ -497,16 +520,16 @@ async fn migrate_unrefreshable_access_tokens(
497520 . into_extract_localpart ( synapse_user_id. clone ( ) ) ?
498521 . to_owned ( ) ;
499522 let Some ( user_infos) = state. users . get ( username. as_str ( ) ) . copied ( ) else {
500- if is_likely_appservice ( & username) {
501- continue ;
502- }
503523 return Err ( Error :: MissingUserFromDependentTable {
504524 table : "access_tokens" . to_owned ( ) ,
505525 user : synapse_user_id,
506526 } ) ;
507527 } ;
508528
509- if user_infos. flags . is_deactivated ( ) || user_infos. flags . is_guest ( ) {
529+ if user_infos. flags . is_deactivated ( )
530+ || user_infos. flags . is_guest ( )
531+ || user_infos. flags . is_appservice ( )
532+ {
510533 continue ;
511534 }
512535
@@ -609,16 +632,16 @@ async fn migrate_refreshable_token_pairs(
609632 . into_extract_localpart ( synapse_user_id. clone ( ) ) ?
610633 . to_owned ( ) ;
611634 let Some ( user_infos) = state. users . get ( username. as_str ( ) ) . copied ( ) else {
612- if is_likely_appservice ( & username) {
613- continue ;
614- }
615635 return Err ( Error :: MissingUserFromDependentTable {
616636 table : "refresh_tokens" . to_owned ( ) ,
617637 user : synapse_user_id,
618638 } ) ;
619639 } ;
620640
621- if user_infos. flags . is_deactivated ( ) || user_infos. flags . is_guest ( ) {
641+ if user_infos. flags . is_deactivated ( )
642+ || user_infos. flags . is_guest ( )
643+ || user_infos. flags . is_appservice ( )
644+ {
622645 continue ;
623646 }
624647
@@ -715,15 +738,3 @@ fn transform_user(
715738
716739 Ok ( ( new_user, mas_password) )
717740}
718-
719- /// Returns true if and only if the given localpart looks like it would belong
720- /// to an application service user.
721- /// The rule here is that it must start with an underscore.
722- /// Synapse reserves these by default, but there is no hard rule prohibiting
723- /// other namespaces from being reserved, so this is not a robust check.
724- // TODO replace with a more robust mechanism, if we even care about this sanity check
725- // e.g. read application service registration files.
726- #[ inline]
727- fn is_likely_appservice ( localpart : & str ) -> bool {
728- localpart. starts_with ( '_' )
729- }
0 commit comments