2024-06-02 00:18:57 +00:00
mod data ;
2024-03-05 19:19:06 -05:00
use std ::{
2024-10-11 18:57:59 +00:00
collections ::HashMap ,
2024-07-04 03:26:19 +00:00
fmt ::Write ,
sync ::{ Arc , RwLock } ,
2024-05-09 15:59:08 -07:00
time ::Instant ,
2022-10-09 17:25:06 +02:00
} ;
2022-08-07 19:42:22 +02:00
2025-01-01 23:49:08 +00:00
use conduwuit ::{ error , utils ::bytes ::pretty , Config , Result } ;
2024-05-26 21:29:19 +00:00
use data ::Data ;
2024-03-05 19:19:06 -05:00
use regex ::RegexSet ;
2024-12-28 23:31:24 +00:00
use ruma ::{ OwnedEventId , OwnedRoomAliasId , OwnedServerName , OwnedUserId , ServerName , UserId } ;
2020-07-23 23:03:24 -04:00
2024-07-22 07:43:51 +00:00
use crate ::service ;
2023-08-01 14:48:50 -10:00
2024-05-09 15:59:08 -07:00
pub struct Service {
2024-05-27 03:17:20 +00:00
pub db : Data ,
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub config : Config ,
pub bad_event_ratelimiter : Arc < RwLock < HashMap < OwnedEventId , RateLimitState > > > ,
2024-06-12 02:10:59 -04:00
pub server_user : OwnedUserId ,
pub admin_alias : OwnedRoomAliasId ,
2024-09-20 22:57:04 -04:00
pub turn_secret : String ,
2024-09-29 01:54:07 -04:00
pub registration_token : Option < String > ,
2021-07-14 12:31:38 +02:00
}
2024-07-09 20:04:43 +00:00
type RateLimitState = ( Instant , u32 ) ; // Time if last failed try, number of failed tries
2024-07-04 03:26:19 +00:00
impl crate ::Service for Service {
fn build ( args : crate ::Args < '_ > ) -> Result < Arc < Self > > {
2024-07-18 06:37:47 +00:00
let db = Data ::new ( & args ) ;
2024-07-04 03:26:19 +00:00
let config = & args . server . config ;
2024-03-05 19:48:54 -05:00
2024-12-15 00:05:47 -05:00
let turn_secret =
2024-09-29 01:54:07 -04:00
config
2024-12-15 00:05:47 -05:00
. turn_secret_file
2024-09-29 01:54:07 -04:00
. as_ref ( )
2024-12-15 00:05:47 -05:00
. map_or ( config . turn_secret . clone ( ) , | path | {
std ::fs ::read_to_string ( path ) . unwrap_or_else ( | e | {
error! ( " Failed to read the TURN secret file: {e} " ) ;
config . turn_secret . clone ( )
} )
2024-09-29 01:54:07 -04:00
} ) ;
2024-12-15 00:05:47 -05:00
let registration_token = config . registration_token_file . as_ref ( ) . map_or (
config . registration_token . clone ( ) ,
| path | {
let Ok ( token ) = std ::fs ::read_to_string ( path ) . inspect_err ( | e | {
error! ( " Failed to read the registration token file: {e} " ) ;
} ) else {
return config . registration_token . clone ( ) ;
} ;
Some ( token )
} ,
) ;
2021-11-05 20:47:11 +00:00
let mut s = Self {
2022-09-07 13:25:51 +02:00
db ,
2024-03-16 15:54:58 -07:00
config : config . clone ( ) ,
2021-01-29 11:20:33 -05:00
bad_event_ratelimiter : Arc ::new ( RwLock ::new ( HashMap ::new ( ) ) ) ,
2024-12-28 23:31:24 +00:00
admin_alias : OwnedRoomAliasId ::try_from ( format! ( " #admins: {} " , & config . server_name ) )
2024-06-12 02:10:59 -04:00
. expect ( " #admins:server_name is valid alias name " ) ,
2024-12-15 00:05:47 -05:00
server_user : UserId ::parse_with_server_name (
String ::from ( " conduit " ) ,
& config . server_name ,
)
. expect ( " @conduit:server_name is valid " ) ,
2024-09-20 22:57:04 -04:00
turn_secret ,
2024-09-29 01:54:07 -04:00
registration_token ,
2024-03-05 19:48:54 -05:00
} ;
2024-12-05 07:23:51 +00:00
if ! args
. server
. supported_room_version ( & config . default_room_version )
2024-03-25 17:05:11 -04:00
{
2024-12-14 21:58:01 -05:00
error! ( config = ? s . config . default_room_version , fallback = ? conduwuit ::config ::default_default_room_version ( ) , " Room version in config isn't supported, falling back to default version " ) ;
s . config . default_room_version = conduwuit ::config ::default_default_room_version ( ) ;
2024-03-05 19:48:54 -05:00
} ;
2024-07-04 03:26:19 +00:00
Ok ( Arc ::new ( s ) )
}
2025-01-01 23:49:08 +00:00
fn memory_usage ( & self , out : & mut dyn Write ) -> Result {
let ( ber_count , ber_bytes ) = self . bad_event_ratelimiter . read ( ) ? . iter ( ) . fold (
( 0_ usize , 0_ usize ) ,
| ( mut count , mut bytes ) , ( event_id , _ ) | {
bytes = bytes . saturating_add ( event_id . capacity ( ) ) ;
bytes = bytes . saturating_add ( size_of ::< RateLimitState > ( ) ) ;
count = count . saturating_add ( 1 ) ;
( count , bytes )
} ,
) ;
writeln! ( out , " bad_event_ratelimiter: {ber_count} ({}) " , pretty ( ber_bytes ) ) ? ;
2024-07-04 03:26:19 +00:00
Ok ( ( ) )
}
fn clear_cache ( & self ) {
self . bad_event_ratelimiter
. write ( )
. expect ( " locked for writing " )
. clear ( ) ;
2024-03-05 19:48:54 -05:00
}
2024-07-16 22:00:54 +00:00
fn name ( & self ) -> & str { service ::make_name ( std ::module_path! ( ) ) }
2024-07-04 03:26:19 +00:00
}
impl Service {
2024-07-02 07:56:45 +00:00
#[ inline ]
2024-05-09 15:59:08 -07:00
pub fn next_count ( & self ) -> Result < u64 > { self . db . next_count ( ) }
2024-03-05 19:48:54 -05:00
2024-07-02 07:56:45 +00:00
#[ inline ]
pub fn current_count ( & self ) -> Result < u64 > { Ok ( self . db . current_count ( ) ) }
2024-03-05 19:48:54 -05:00
2024-07-16 08:05:25 +00:00
#[ inline ]
2024-05-09 15:59:08 -07:00
pub fn server_name ( & self ) -> & ServerName { self . config . server_name . as_ref ( ) }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_registration ( & self ) -> bool { self . config . allow_registration }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_guest_registration ( & self ) -> bool { self . config . allow_guest_registration }
2024-03-05 19:48:54 -05:00
2024-12-15 00:05:47 -05:00
pub fn allow_guests_auto_join_rooms ( & self ) -> bool {
self . config . allow_guests_auto_join_rooms
}
2024-04-13 20:33:24 -04:00
2024-05-09 15:59:08 -07:00
pub fn log_guest_registrations ( & self ) -> bool { self . config . log_guest_registrations }
2024-04-13 20:19:10 -04:00
2024-05-09 15:59:08 -07:00
pub fn allow_encryption ( & self ) -> bool { self . config . allow_encryption }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_federation ( & self ) -> bool { self . config . allow_federation }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_public_room_directory_over_federation ( & self ) -> bool {
2022-01-28 12:42:47 -06:00
self . config . allow_public_room_directory_over_federation
2020-05-03 17:25:31 +02:00
}
2024-03-05 19:48:54 -05:00
2024-12-15 00:05:47 -05:00
pub fn allow_device_name_federation ( & self ) -> bool {
self . config . allow_device_name_federation
}
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_room_creation ( & self ) -> bool { self . config . allow_room_creation }
2024-03-05 19:48:54 -05:00
2024-12-15 00:05:47 -05:00
pub fn new_user_displayname_suffix ( & self ) -> & String {
& self . config . new_user_displayname_suffix
}
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_check_for_updates ( & self ) -> bool { self . config . allow_check_for_updates }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn trusted_servers ( & self ) -> & [ OwnedServerName ] { & self . config . trusted_servers }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn turn_password ( & self ) -> & String { & self . config . turn_password }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn turn_ttl ( & self ) -> u64 { self . config . turn_ttl }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn turn_uris ( & self ) -> & [ String ] { & self . config . turn_uris }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn turn_username ( & self ) -> & String { & self . config . turn_username }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn notification_push_path ( & self ) -> & String { & self . config . notification_push_path }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn emergency_password ( & self ) -> & Option < String > { & self . config . emergency_password }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn url_preview_domain_contains_allowlist ( & self ) -> & Vec < String > {
2021-01-01 13:47:53 +01:00
& self . config . url_preview_domain_contains_allowlist
2020-06-06 19:02:31 +02:00
}
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn url_preview_domain_explicit_allowlist ( & self ) -> & Vec < String > {
2023-12-21 20:44:58 -05:00
& self . config . url_preview_domain_explicit_allowlist
2024-03-05 19:48:54 -05:00
}
2024-05-09 15:59:08 -07:00
pub fn url_preview_domain_explicit_denylist ( & self ) -> & Vec < String > {
2024-04-14 21:12:48 -04:00
& self . config . url_preview_domain_explicit_denylist
}
2024-12-15 00:05:47 -05:00
pub fn url_preview_url_contains_allowlist ( & self ) -> & Vec < String > {
& self . config . url_preview_url_contains_allowlist
}
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn url_preview_max_spider_size ( & self ) -> usize { self . config . url_preview_max_spider_size }
2024-03-05 19:48:54 -05:00
2024-12-15 00:05:47 -05:00
pub fn url_preview_check_root_domain ( & self ) -> bool {
self . config . url_preview_check_root_domain
}
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn forbidden_alias_names ( & self ) -> & RegexSet { & self . config . forbidden_alias_names }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn forbidden_usernames ( & self ) -> & RegexSet { & self . config . forbidden_usernames }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_local_presence ( & self ) -> bool { self . config . allow_local_presence }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_incoming_presence ( & self ) -> bool { self . config . allow_incoming_presence }
2024-03-05 19:48:54 -05:00
2024-05-09 15:59:08 -07:00
pub fn allow_outgoing_presence ( & self ) -> bool { self . config . allow_outgoing_presence }
2024-03-05 19:48:54 -05:00
2024-12-15 00:05:47 -05:00
pub fn allow_incoming_read_receipts ( & self ) -> bool {
self . config . allow_incoming_read_receipts
}
2024-03-17 12:16:04 -04:00
2024-12-15 00:05:47 -05:00
pub fn allow_outgoing_read_receipts ( & self ) -> bool {
self . config . allow_outgoing_read_receipts
}
2024-04-10 15:22:50 -07:00
2024-05-09 15:59:08 -07:00
pub fn block_non_admin_invites ( & self ) -> bool { self . config . block_non_admin_invites }
2024-03-05 19:48:54 -05:00
2024-07-22 07:43:51 +00:00
/// checks if `user_id` is local to us via server_name comparison
#[ inline ]
2024-12-15 00:05:47 -05:00
pub fn user_is_local ( & self , user_id : & UserId ) -> bool {
self . server_is_ours ( user_id . server_name ( ) )
}
2024-03-05 19:48:54 -05:00
2024-07-22 07:43:51 +00:00
#[ inline ]
2024-12-15 00:05:47 -05:00
pub fn server_is_ours ( & self , server_name : & ServerName ) -> bool {
server_name = = self . config . server_name
}
2024-10-01 04:20:31 +00:00
#[ inline ]
pub fn is_read_only ( & self ) -> bool { self . db . db . is_read_only ( ) }
2024-07-22 07:43:51 +00:00
}