Skip to content

Commit

Permalink
cleanup+refactor admin room alias and server account accessing to glo…
Browse files Browse the repository at this point in the history
…bals

Signed-off-by: strawberry <[email protected]>
  • Loading branch information
girlbossceo committed Jun 12, 2024
1 parent f712c0c commit 8fff7ea
Show file tree
Hide file tree
Showing 12 changed files with 77 additions and 101 deletions.
11 changes: 5 additions & 6 deletions src/admin/room/room_alias_commands.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use std::fmt::Write;

use ruma::{events::room::message::RoomMessageEventContent, RoomAliasId, UserId};
use ruma::{events::room::message::RoomMessageEventContent, RoomAliasId};

use super::RoomAliasCommand;
use crate::{escape_html, services, Result};

pub(crate) async fn process(command: RoomAliasCommand, _body: Vec<&str>) -> Result<RoomMessageEventContent> {
let server_user = UserId::parse_with_server_name(String::from("conduit"), services().globals.server_name())
.expect("server's username is valid");
let server_user = &services().globals.server_user;

match command {
RoomAliasCommand::Set {
Expand All @@ -34,7 +33,7 @@ pub(crate) async fn process(command: RoomAliasCommand, _body: Vec<&str>) -> Resu
(true, Ok(Some(id))) => match services()
.rooms
.alias
.set_alias(&room_alias, &room_id, &server_user)
.set_alias(&room_alias, &room_id, server_user)
{
Ok(()) => Ok(RoomMessageEventContent::text_plain(format!(
"Successfully overwrote alias (formerly {id})"
Expand All @@ -47,7 +46,7 @@ pub(crate) async fn process(command: RoomAliasCommand, _body: Vec<&str>) -> Resu
(_, Ok(None)) => match services()
.rooms
.alias
.set_alias(&room_alias, &room_id, &server_user)
.set_alias(&room_alias, &room_id, server_user)
{
Ok(()) => Ok(RoomMessageEventContent::text_plain("Successfully set alias")),
Err(err) => Ok(RoomMessageEventContent::text_plain(format!("Failed to remove alias: {err}"))),
Expand All @@ -60,7 +59,7 @@ pub(crate) async fn process(command: RoomAliasCommand, _body: Vec<&str>) -> Resu
Ok(Some(id)) => match services()
.rooms
.alias
.remove_alias(&room_alias, &server_user)
.remove_alias(&room_alias, server_user)
.await
{
Ok(()) => Ok(RoomMessageEventContent::text_plain(format!("Removed alias from {id}"))),
Expand Down
16 changes: 6 additions & 10 deletions src/admin/room/room_moderation_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,10 @@ async fn ban_room(
) -> Result<RoomMessageEventContent> {
debug!("Got room alias or ID: {}", room);

let admin_room_alias: Box<RoomAliasId> = format!("#admins:{}", services().globals.server_name())
.try_into()
.expect("#admins:server_name is a valid alias name");
let admin_room_alias = &services().globals.admin_alias;

if let Some(admin_room_id) = Service::get_admin_room().await? {
if room.to_string().eq(&admin_room_id) || room.to_string().eq(&admin_room_alias) {
if let Some(admin_room_id) = Service::get_admin_room()? {
if room.to_string().eq(&admin_room_id) || room.to_string().eq(admin_room_alias) {
return Ok(RoomMessageEventContent::text_plain("Not allowed to ban the admin room."));
}
}
Expand Down Expand Up @@ -192,18 +190,16 @@ async fn ban_list_of_rooms(body: Vec<&str>, force: bool, disable_federation: boo

let rooms_s = body.clone().drain(1..body.len() - 1).collect::<Vec<_>>();

let admin_room_alias: Box<RoomAliasId> = format!("#admins:{}", services().globals.server_name())
.try_into()
.expect("#admins:server_name is a valid alias name");
let admin_room_alias = &services().globals.admin_alias;

let mut room_ban_count: usize = 0;
let mut room_ids: Vec<OwnedRoomId> = Vec::new();

for &room in &rooms_s {
match <&RoomOrAliasId>::try_from(room) {
Ok(room_alias_or_id) => {
if let Some(admin_room_id) = Service::get_admin_room().await? {
if room.to_owned().eq(&admin_room_id) || room.to_owned().eq(&admin_room_alias) {
if let Some(admin_room_id) = Service::get_admin_room()? {
if room.to_owned().eq(&admin_room_id) || room.to_owned().eq(admin_room_alias) {
info!("User specified admin room in bulk ban list, ignoring");
continue;
}
Expand Down
15 changes: 4 additions & 11 deletions src/admin/user/user_commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use ruma::{
tag::{TagEvent, TagEventContent, TagInfo},
RoomAccountDataEventType,
},
OwnedRoomId, OwnedUserId, RoomId, UserId,
OwnedRoomId, OwnedUserId, RoomId,
};
use tracing::{error, info, warn};

Expand Down Expand Up @@ -134,9 +134,7 @@ pub(crate) async fn deactivate(
let user_id = parse_local_user_id(&user_id)?;

// don't deactivate the server service account
if user_id
== UserId::parse_with_server_name("conduit", services().globals.server_name()).expect("conduit user exists")
{
if user_id == services().globals.server_user {
return Ok(RoomMessageEventContent::text_plain(
"Not allowed to deactivate the server service account.",
));
Expand Down Expand Up @@ -171,9 +169,7 @@ pub(crate) async fn deactivate(
pub(crate) async fn reset_password(_body: Vec<&str>, username: String) -> Result<RoomMessageEventContent> {
let user_id = parse_local_user_id(&username)?;

if user_id
== UserId::parse_with_server_name("conduit", services().globals.server_name()).expect("conduit user exists")
{
if user_id == services().globals.server_user {
return Ok(RoomMessageEventContent::text_plain(
"Not allowed to set the password for the server account. Please use the emergency password config option.",
));
Expand Down Expand Up @@ -223,10 +219,7 @@ pub(crate) async fn deactivate_all(
}

// don't deactivate the server service account
if user_id
== UserId::parse_with_server_name("conduit", services().globals.server_name())
.expect("server user exists")
{
if user_id == services().globals.server_user {
services()
.admin
.send_message(RoomMessageEventContent::text_plain(format!(
Expand Down
2 changes: 1 addition & 1 deletion src/api/client/account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ pub(crate) async fn register_route(
// If this is the first real user, grant them admin privileges except for guest
// users Note: the server user, @conduit:servername, is generated first
if !is_guest {
if let Some(admin_room) = service::admin::Service::get_admin_room().await? {
if let Some(admin_room) = service::admin::Service::get_admin_room()? {
if services()
.rooms
.state_cache
Expand Down
4 changes: 2 additions & 2 deletions src/api/client/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ async fn allowed_to_send_state_event(
},
// admin room is a sensitive room, it should not ever be made public
StateEventType::RoomJoinRules => {
if let Some(admin_room_id) = service::admin::Service::get_admin_room().await? {
if let Some(admin_room_id) = service::admin::Service::get_admin_room()? {
if admin_room_id == room_id {
if let Ok(join_rule) = serde_json::from_str::<RoomJoinRulesEventContent>(json.json().get()) {
if join_rule.join_rule == JoinRule::Public {
Expand All @@ -231,7 +231,7 @@ async fn allowed_to_send_state_event(
},
// admin room is a sensitive room, it should not ever be made world readable
StateEventType::RoomHistoryVisibility => {
if let Some(admin_room_id) = service::admin::Service::get_admin_room().await? {
if let Some(admin_room_id) = service::admin::Service::get_admin_room()? {
if admin_room_id == room_id {
if let Ok(visibility_content) =
serde_json::from_str::<RoomHistoryVisibilityEventContent>(json.json().get())
Expand Down
61 changes: 26 additions & 35 deletions src/service/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use ruma::{
},
TimelineEventType,
},
EventId, OwnedRoomAliasId, OwnedRoomId, OwnedUserId, RoomAliasId, RoomId, RoomVersionId, UserId,
EventId, OwnedRoomId, OwnedUserId, RoomId, RoomVersionId, UserId,
};
use serde_json::value::to_raw_value;
use tokio::{sync::Mutex, task::JoinHandle};
Expand Down Expand Up @@ -69,18 +69,17 @@ impl Service {

async fn handler(self: &Arc<Self>) -> Result<()> {
let receiver = self.receiver.lock().await;
let Ok(Some(admin_room)) = Self::get_admin_room().await else {
let Ok(Some(admin_room)) = Self::get_admin_room() else {
return Ok(());
};

let server_user = UserId::parse_with_server_name(String::from("conduit"), services().globals.server_name())
.expect("server's username is valid");
let server_user = &services().globals.server_user;

loop {
debug_assert!(!receiver.is_closed(), "channel closed");
tokio::select! {
event = receiver.recv_async() => match event {
Ok(event) => self.receive(event, &admin_room, &server_user).await?,
Ok(event) => self.receive(event, &admin_room, server_user).await?,
Err(_e) => return Ok(()),
}
}
Expand Down Expand Up @@ -130,15 +129,11 @@ impl Service {
///
/// Errors are propagated from the database, and will have None if there is
/// no admin room
pub async fn get_admin_room() -> Result<Option<OwnedRoomId>> {
let admin_room_alias: Box<RoomAliasId> = format!("#admins:{}", services().globals.server_name())
.try_into()
.expect("#admins:server_name is a valid alias name");

pub fn get_admin_room() -> Result<Option<OwnedRoomId>> {
services()
.rooms
.alias
.resolve_local_alias(&admin_room_alias)
.resolve_local_alias(&services().globals.admin_alias)
}

/// Create the admin room.
Expand All @@ -162,10 +157,9 @@ impl Service {
let state_lock = mutex_state.lock().await;

// Create a user for the server
let server_user = UserId::parse_with_server_name("conduit", services().globals.server_name())
.expect("@conduit:server_name is valid");
let server_user = &services().globals.server_user;

services().users.create(&server_user, None)?;
services().users.create(server_user, None)?;

let room_version = services().globals.default_room_version();
let mut content = match room_version {
Expand Down Expand Up @@ -205,7 +199,7 @@ impl Service {
state_key: Some(String::new()),
redacts: None,
},
&server_user,
server_user,
&room_id,
&state_lock,
)
Expand Down Expand Up @@ -233,7 +227,7 @@ impl Service {
state_key: Some(server_user.to_string()),
redacts: None,
},
&server_user,
server_user,
&room_id,
&state_lock,
)
Expand All @@ -258,7 +252,7 @@ impl Service {
state_key: Some(String::new()),
redacts: None,
},
&server_user,
server_user,
&room_id,
&state_lock,
)
Expand All @@ -277,7 +271,7 @@ impl Service {
state_key: Some(String::new()),
redacts: None,
},
&server_user,
server_user,
&room_id,
&state_lock,
)
Expand All @@ -296,7 +290,7 @@ impl Service {
state_key: Some(String::new()),
redacts: None,
},
&server_user,
server_user,
&room_id,
&state_lock,
)
Expand All @@ -315,7 +309,7 @@ impl Service {
state_key: Some(String::new()),
redacts: None,
},
&server_user,
server_user,
&room_id,
&state_lock,
)
Expand All @@ -335,7 +329,7 @@ impl Service {
state_key: Some(String::new()),
redacts: None,
},
&server_user,
server_user,
&room_id,
&state_lock,
)
Expand All @@ -355,16 +349,14 @@ impl Service {
state_key: Some(String::new()),
redacts: None,
},
&server_user,
server_user,
&room_id,
&state_lock,
)
.await?;

// 6. Room alias
let alias: OwnedRoomAliasId = format!("#admins:{}", services().globals.server_name())
.try_into()
.expect("#admins:server_name is a valid alias name");
let alias = &services().globals.admin_alias;

services()
.rooms
Expand All @@ -381,7 +373,7 @@ impl Service {
state_key: Some(String::new()),
redacts: None,
},
&server_user,
server_user,
&room_id,
&state_lock,
)
Expand All @@ -390,7 +382,7 @@ impl Service {
services()
.rooms
.alias
.set_alias(&alias, &room_id, &server_user)?;
.set_alias(alias, &room_id, server_user)?;

// 7. (ad-hoc) Disable room previews for everyone by default
services()
Expand All @@ -407,7 +399,7 @@ impl Service {
state_key: Some(String::new()),
redacts: None,
},
&server_user,
server_user,
&room_id,
&state_lock,
)
Expand All @@ -420,7 +412,7 @@ impl Service {
///
/// In conduit, this is equivalent to granting admin privileges.
pub async fn make_user_admin(&self, user_id: &UserId, displayname: String) -> Result<()> {
if let Some(room_id) = Self::get_admin_room().await? {
if let Some(room_id) = Self::get_admin_room()? {
let mutex_state = Arc::clone(
services()
.globals
Expand All @@ -433,8 +425,7 @@ impl Service {
let state_lock = mutex_state.lock().await;

// Use the server user to grant the new admin's power level
let server_user = UserId::parse_with_server_name("conduit", services().globals.server_name())
.expect("@conduit:server_name is valid");
let server_user = &services().globals.server_user;

// Invite and join the real user
services()
Expand All @@ -458,7 +449,7 @@ impl Service {
state_key: Some(user_id.to_string()),
redacts: None,
},
&server_user,
server_user,
&room_id,
&state_lock,
)
Expand Down Expand Up @@ -510,7 +501,7 @@ impl Service {
state_key: Some(String::new()),
redacts: None,
},
&server_user,
server_user,
&room_id,
&state_lock,
)
Expand All @@ -529,7 +520,7 @@ impl Service {
state_key: None,
redacts: None,
},
&server_user,
server_user,
&room_id,
&state_lock,
).await?;
Expand All @@ -540,7 +531,7 @@ impl Service {

/// Checks whether a given user is an admin of this server
pub async fn user_is_admin(&self, user_id: &UserId) -> Result<bool> {
let Ok(Some(admin_room)) = Self::get_admin_room().await else {
let Ok(Some(admin_room)) = Self::get_admin_room() else {
return Ok(false);
};

Expand Down
Loading

0 comments on commit 8fff7ea

Please sign in to comment.