2024-06-14 22:08:44 +00:00
use std ::collections ::BTreeMap ;
2024-06-10 06:02:17 +00:00
2026-04-10 11:47:01 -04:00
use conduwuit ::{ Result , info , pdu ::PartialPdu };
2025-04-08 03:17:23 +00:00
use futures ::FutureExt ;
2024-06-10 06:02:17 +00:00
use ruma ::{
2025-02-23 01:17:45 -05:00
RoomId , RoomVersionId ,
2024-10-04 20:25:32 +00:00
events ::room ::{
canonical_alias ::RoomCanonicalAliasEventContent ,
create ::RoomCreateEventContent ,
guest_access ::{ GuestAccess , RoomGuestAccessEventContent },
history_visibility ::{ HistoryVisibility , RoomHistoryVisibilityEventContent },
join_rules ::{ JoinRule , RoomJoinRulesEventContent },
member ::{ MembershipState , RoomMemberEventContent },
name ::RoomNameEventContent ,
power_levels ::RoomPowerLevelsEventContent ,
topic ::RoomTopicEventContent ,
2024-06-10 06:02:17 +00:00
},
};
2024-07-20 23:38:20 +00:00
use crate ::Services ;
2024-06-10 06:02:17 +00:00
/// Create the admin room.
///
2025-03-02 23:16:30 -05:00
/// Users in this room are considered admins by conduwuit, and the room can be
2024-06-10 06:02:17 +00:00
/// used to issue admin commands by talking to the server user inside it.
2025-03-02 23:16:30 -05:00
pub async fn create_admin_room ( services : & Services ) -> Result {
2026-03-29 12:25:42 -04:00
let room_id = RoomId ::new_v1 ( services . globals . server_name ());
2025-09-17 20:46:03 +00:00
let room_version = & RoomVersionId ::V11 ;
2024-06-10 06:02:17 +00:00
2024-09-21 16:28:46 -04:00
let _short_id = services
. rooms
. short
. get_or_create_shortroomid ( & room_id )
. await ;
2024-06-10 06:02:17 +00:00
2026-03-29 12:25:42 -04:00
let state_lock = services . rooms . state . mutex . lock ( room_id . as_str ()). await ;
2024-06-10 06:02:17 +00:00
// Create a user for the server
2025-03-02 23:16:30 -05:00
let server_user = services . globals . server_user . as_ref ();
2026-05-04 11:27:47 -04:00
services . users . create ( server_user , None ). await ? ;
2024-06-10 06:02:17 +00:00
2026-03-29 12:25:42 -04:00
let mut create_content = {
2024-07-12 01:08:53 +00:00
use RoomVersionId ::* ;
match room_version {
2024-12-15 00:05:47 -05:00
| V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 =>
2025-03-02 23:16:30 -05:00
RoomCreateEventContent ::new_v1 ( server_user . into ()),
2026-03-29 12:25:42 -04:00
| _ => RoomCreateEventContent ::new_v11 (),
2024-07-12 01:08:53 +00:00
}
2024-06-10 06:02:17 +00:00
};
2026-03-29 12:25:42 -04:00
create_content . federate = true ;
create_content . room_version = room_version . clone ();
2025-09-17 20:46:03 +00:00
info! ( "Creating admin room {} with version {}" , room_id , room_version );
2024-06-10 06:02:17 +00:00
// 1. The room create event
2024-07-20 23:38:20 +00:00
services
2024-06-10 06:02:17 +00:00
. rooms
. timeline
. build_and_append_pdu (
2026-04-10 11:47:01 -04:00
PartialPdu ::state ( String ::new (), & create_content ),
2024-06-10 06:02:17 +00:00
server_user ,
2025-09-17 20:46:03 +00:00
Some ( & room_id ),
2024-06-10 06:02:17 +00:00
& state_lock ,
)
2025-04-08 03:17:23 +00:00
. boxed ()
2024-06-10 06:02:17 +00:00
. await ? ;
2024-12-14 21:58:01 -05:00
// 2. Make server user/bot join
2024-07-20 23:38:20 +00:00
services
2024-06-10 06:02:17 +00:00
. rooms
. timeline
. build_and_append_pdu (
2026-04-10 11:47:01 -04:00
PartialPdu ::state (
2025-03-02 23:16:30 -05:00
String ::from ( server_user ),
2024-12-15 00:05:47 -05:00
& RoomMemberEventContent ::new ( MembershipState ::Join ),
),
2024-06-10 06:02:17 +00:00
server_user ,
2025-09-17 20:46:03 +00:00
Some ( & room_id ),
2024-06-10 06:02:17 +00:00
& state_lock ,
)
2025-04-08 03:17:23 +00:00
. boxed ()
2024-06-10 06:02:17 +00:00
. await ? ;
// 3. Power levels
2025-03-02 23:16:30 -05:00
let users = BTreeMap ::from_iter ([( server_user . into (), 69420. into ())]);
2024-06-10 06:02:17 +00:00
2026-04-07 14:40:10 +01:00
let mut power_levels_content =
RoomPowerLevelsEventContent ::new ( & room_version . rules (). unwrap (). authorization );
2026-03-29 12:25:42 -04:00
power_levels_content . users = users ;
2024-07-20 23:38:20 +00:00
services
2024-06-10 06:02:17 +00:00
. rooms
. timeline
. build_and_append_pdu (
2026-04-10 11:47:01 -04:00
PartialPdu ::state ( String ::new (), & power_levels_content ),
2024-06-10 06:02:17 +00:00
server_user ,
2025-09-17 20:46:03 +00:00
Some ( & room_id ),
2024-06-10 06:02:17 +00:00
& state_lock ,
)
2025-04-08 03:17:23 +00:00
. boxed ()
2024-06-10 06:02:17 +00:00
. await ? ;
// 4.1 Join Rules
2024-07-20 23:38:20 +00:00
services
2024-06-10 06:02:17 +00:00
. rooms
. timeline
. build_and_append_pdu (
2026-04-10 11:47:01 -04:00
PartialPdu ::state ( String ::new (), & RoomJoinRulesEventContent ::new ( JoinRule ::Invite )),
2024-06-10 06:02:17 +00:00
server_user ,
2025-09-17 20:46:03 +00:00
Some ( & room_id ),
2024-06-10 06:02:17 +00:00
& state_lock ,
)
2025-04-08 03:17:23 +00:00
. boxed ()
2024-06-10 06:02:17 +00:00
. await ? ;
// 4.2 History Visibility
2024-07-20 23:38:20 +00:00
services
2024-06-10 06:02:17 +00:00
. rooms
. timeline
. build_and_append_pdu (
2026-04-10 11:47:01 -04:00
PartialPdu ::state (
2024-10-04 20:25:32 +00:00
String ::new (),
& RoomHistoryVisibilityEventContent ::new ( HistoryVisibility ::Shared ),
),
2024-06-10 06:02:17 +00:00
server_user ,
2025-09-17 20:46:03 +00:00
Some ( & room_id ),
2024-06-10 06:02:17 +00:00
& state_lock ,
)
2025-04-08 03:17:23 +00:00
. boxed ()
2024-06-10 06:02:17 +00:00
. await ? ;
// 4.3 Guest Access
2024-07-20 23:38:20 +00:00
services
2024-06-10 06:02:17 +00:00
. rooms
. timeline
. build_and_append_pdu (
2026-04-10 11:47:01 -04:00
PartialPdu ::state (
2024-12-15 00:05:47 -05:00
String ::new (),
& RoomGuestAccessEventContent ::new ( GuestAccess ::Forbidden ),
),
2024-06-10 06:02:17 +00:00
server_user ,
2025-09-17 20:46:03 +00:00
Some ( & room_id ),
2024-06-10 06:02:17 +00:00
& state_lock ,
)
2025-04-08 03:17:23 +00:00
. boxed ()
2024-06-10 06:02:17 +00:00
. await ? ;
// 5. Events implied by name and topic
2025-03-02 23:16:30 -05:00
let room_name = format! ( " {} Admin Room" , services . config . server_name );
2024-07-20 23:38:20 +00:00
services
2024-06-10 06:02:17 +00:00
. rooms
. timeline
. build_and_append_pdu (
2026-04-10 11:47:01 -04:00
PartialPdu ::state ( String ::new (), & RoomNameEventContent ::new ( room_name )),
2024-06-10 06:02:17 +00:00
server_user ,
2025-09-17 20:46:03 +00:00
Some ( & room_id ),
2024-06-10 06:02:17 +00:00
& state_lock ,
)
2025-04-08 03:17:23 +00:00
. boxed ()
2024-06-10 06:02:17 +00:00
. await ? ;
2026-03-29 12:25:42 -04:00
let room_topic = format! ( "Manage {} | Run commands prefixed with `!admin` | Run `!admin -h` for help | Documentation: https://continuwuity.org/" , services . config . server_name );
2024-07-20 23:38:20 +00:00
services
2024-06-10 06:02:17 +00:00
. rooms
. timeline
. build_and_append_pdu (
2026-04-10 11:47:01 -04:00
PartialPdu ::state ( String ::new (), & RoomTopicEventContent ::markdown ( room_topic )),
2024-06-10 06:02:17 +00:00
server_user ,
2025-09-17 20:46:03 +00:00
Some ( & room_id ),
2024-06-10 06:02:17 +00:00
& state_lock ,
)
2025-04-08 03:17:23 +00:00
. boxed ()
2024-06-10 06:02:17 +00:00
. await ? ;
// 6. Room alias
2026-03-29 12:25:42 -04:00
let mut alias_content = RoomCanonicalAliasEventContent ::new ();
alias_content . alias = Some ( services . globals . admin_alias . clone ());
2024-06-10 06:02:17 +00:00
2024-07-20 23:38:20 +00:00
services
2024-06-10 06:02:17 +00:00
. rooms
. timeline
. build_and_append_pdu (
2026-04-10 11:47:01 -04:00
PartialPdu ::state ( String ::new (), & alias_content ),
2024-06-10 06:02:17 +00:00
server_user ,
2025-09-17 20:46:03 +00:00
Some ( & room_id ),
2024-06-10 06:02:17 +00:00
& state_lock ,
)
2025-04-08 03:17:23 +00:00
. boxed ()
2024-06-10 06:02:17 +00:00
. await ? ;
2024-07-20 23:38:20 +00:00
services
2024-06-10 06:02:17 +00:00
. rooms
. alias
2026-03-29 12:25:42 -04:00
. set_alias ( & services . globals . admin_alias , & room_id , server_user ) ? ;
2024-06-10 06:02:17 +00:00
Ok (())
}