de-global services for services
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
992c0a1e58
commit
010e4ee35a
85 changed files with 2480 additions and 1887 deletions
|
@ -11,10 +11,11 @@ use rustyline_async::{Readline, ReadlineError, ReadlineEvent};
|
|||
use termimad::MadSkin;
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
use crate::services;
|
||||
use crate::{admin, Dep};
|
||||
|
||||
pub struct Console {
|
||||
server: Arc<Server>,
|
||||
admin: Dep<admin::Service>,
|
||||
worker_join: Mutex<Option<JoinHandle<()>>>,
|
||||
input_abort: Mutex<Option<AbortHandle>>,
|
||||
command_abort: Mutex<Option<AbortHandle>>,
|
||||
|
@ -29,6 +30,7 @@ impl Console {
|
|||
pub(super) fn new(args: &crate::Args<'_>) -> Arc<Self> {
|
||||
Arc::new(Self {
|
||||
server: args.server.clone(),
|
||||
admin: args.depend::<admin::Service>("admin"),
|
||||
worker_join: None.into(),
|
||||
input_abort: None.into(),
|
||||
command_abort: None.into(),
|
||||
|
@ -116,7 +118,8 @@ impl Console {
|
|||
let _suppression = log::Suppress::new(&self.server);
|
||||
|
||||
let (mut readline, _writer) = Readline::new(PROMPT.to_owned())?;
|
||||
readline.set_tab_completer(Self::tab_complete);
|
||||
let self_ = Arc::clone(self);
|
||||
readline.set_tab_completer(move |line| self_.tab_complete(line));
|
||||
self.set_history(&mut readline);
|
||||
|
||||
let future = readline.readline();
|
||||
|
@ -154,7 +157,7 @@ impl Console {
|
|||
}
|
||||
|
||||
async fn process(self: Arc<Self>, line: String) {
|
||||
match services().admin.command_in_place(line, None).await {
|
||||
match self.admin.command_in_place(line, None).await {
|
||||
Ok(Some(content)) => self.output(content).await,
|
||||
Err(e) => error!("processing command: {e}"),
|
||||
_ => (),
|
||||
|
@ -184,9 +187,8 @@ impl Console {
|
|||
history.truncate(HISTORY_LIMIT);
|
||||
}
|
||||
|
||||
fn tab_complete(line: &str) -> String {
|
||||
services()
|
||||
.admin
|
||||
fn tab_complete(&self, line: &str) -> String {
|
||||
self.admin
|
||||
.complete_command(line)
|
||||
.unwrap_or_else(|| line.to_owned())
|
||||
}
|
||||
|
|
|
@ -25,13 +25,14 @@ impl super::Service {
|
|||
return Ok(());
|
||||
};
|
||||
|
||||
let state_lock = self.state.mutex.lock(&room_id).await;
|
||||
let state_lock = self.services.state.mutex.lock(&room_id).await;
|
||||
|
||||
// Use the server user to grant the new admin's power level
|
||||
let server_user = &self.globals.server_user;
|
||||
let server_user = &self.services.globals.server_user;
|
||||
|
||||
// Invite and join the real user
|
||||
self.timeline
|
||||
self.services
|
||||
.timeline
|
||||
.build_and_append_pdu(
|
||||
PduBuilder {
|
||||
event_type: TimelineEventType::RoomMember,
|
||||
|
@ -55,7 +56,8 @@ impl super::Service {
|
|||
&state_lock,
|
||||
)
|
||||
.await?;
|
||||
self.timeline
|
||||
self.services
|
||||
.timeline
|
||||
.build_and_append_pdu(
|
||||
PduBuilder {
|
||||
event_type: TimelineEventType::RoomMember,
|
||||
|
@ -85,7 +87,8 @@ impl super::Service {
|
|||
users.insert(server_user.clone(), 100.into());
|
||||
users.insert(user_id.to_owned(), 100.into());
|
||||
|
||||
self.timeline
|
||||
self.services
|
||||
.timeline
|
||||
.build_and_append_pdu(
|
||||
PduBuilder {
|
||||
event_type: TimelineEventType::RoomPowerLevels,
|
||||
|
@ -105,12 +108,12 @@ impl super::Service {
|
|||
.await?;
|
||||
|
||||
// Send welcome message
|
||||
self.timeline.build_and_append_pdu(
|
||||
self.services.timeline.build_and_append_pdu(
|
||||
PduBuilder {
|
||||
event_type: TimelineEventType::RoomMessage,
|
||||
content: to_raw_value(&RoomMessageEventContent::text_html(
|
||||
format!("## Thank you for trying out conduwuit!\n\nconduwuit is a fork of upstream Conduit which is in Beta. This means you can join and participate in most Matrix rooms, but not all features are supported and you might run into bugs from time to time.\n\nHelpful links:\n> Git and Documentation: https://github.com/girlbossceo/conduwuit\n> Report issues: https://github.com/girlbossceo/conduwuit/issues\n\nFor a list of available commands, send the following message in this room: `@conduit:{}: --help`\n\nHere are some rooms you can join (by typing the command):\n\nconduwuit room (Ask questions and get notified on updates):\n`/join #conduwuit:puppygock.gay`", self.globals.server_name()),
|
||||
format!("<h2>Thank you for trying out conduwuit!</h2>\n<p>conduwuit is a fork of upstream Conduit which is in Beta. This means you can join and participate in most Matrix rooms, but not all features are supported and you might run into bugs from time to time.</p>\n<p>Helpful links:</p>\n<blockquote>\n<p>Git and Documentation: https://github.com/girlbossceo/conduwuit<br>Report issues: https://github.com/girlbossceo/conduwuit/issues</p>\n</blockquote>\n<p>For a list of available commands, send the following message in this room: <code>@conduit:{}: --help</code></p>\n<p>Here are some rooms you can join (by typing the command):</p>\n<p>conduwuit room (Ask questions and get notified on updates):<br><code>/join #conduwuit:puppygock.gay</code></p>\n", self.globals.server_name()),
|
||||
format!("## Thank you for trying out conduwuit!\n\nconduwuit is a fork of upstream Conduit which is in Beta. This means you can join and participate in most Matrix rooms, but not all features are supported and you might run into bugs from time to time.\n\nHelpful links:\n> Git and Documentation: https://github.com/girlbossceo/conduwuit\n> Report issues: https://github.com/girlbossceo/conduwuit/issues\n\nFor a list of available commands, send the following message in this room: `@conduit:{}: --help`\n\nHere are some rooms you can join (by typing the command):\n\nconduwuit room (Ask questions and get notified on updates):\n`/join #conduwuit:puppygock.gay`", self.services.globals.server_name()),
|
||||
format!("<h2>Thank you for trying out conduwuit!</h2>\n<p>conduwuit is a fork of upstream Conduit which is in Beta. This means you can join and participate in most Matrix rooms, but not all features are supported and you might run into bugs from time to time.</p>\n<p>Helpful links:</p>\n<blockquote>\n<p>Git and Documentation: https://github.com/girlbossceo/conduwuit<br>Report issues: https://github.com/girlbossceo/conduwuit/issues</p>\n</blockquote>\n<p>For a list of available commands, send the following message in this room: <code>@conduit:{}: --help</code></p>\n<p>Here are some rooms you can join (by typing the command):</p>\n<p>conduwuit room (Ask questions and get notified on updates):<br><code>/join #conduwuit:puppygock.gay</code></p>\n", self.services.globals.server_name()),
|
||||
))
|
||||
.expect("event is valid, we just created it"),
|
||||
unsigned: None,
|
||||
|
|
|
@ -22,15 +22,10 @@ use ruma::{
|
|||
use serde_json::value::to_raw_value;
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
|
||||
use crate::{globals, rooms, rooms::state::RoomMutexGuard, user_is_local};
|
||||
use crate::{globals, rooms, rooms::state::RoomMutexGuard, user_is_local, Dep};
|
||||
|
||||
pub struct Service {
|
||||
server: Arc<Server>,
|
||||
globals: Arc<globals::Service>,
|
||||
alias: Arc<rooms::alias::Service>,
|
||||
timeline: Arc<rooms::timeline::Service>,
|
||||
state: Arc<rooms::state::Service>,
|
||||
state_cache: Arc<rooms::state_cache::Service>,
|
||||
services: Services,
|
||||
sender: Sender<Command>,
|
||||
receiver: Mutex<Receiver<Command>>,
|
||||
pub handle: RwLock<Option<Handler>>,
|
||||
|
@ -39,6 +34,15 @@ pub struct Service {
|
|||
pub console: Arc<console::Console>,
|
||||
}
|
||||
|
||||
struct Services {
|
||||
server: Arc<Server>,
|
||||
globals: Dep<globals::Service>,
|
||||
alias: Dep<rooms::alias::Service>,
|
||||
timeline: Dep<rooms::timeline::Service>,
|
||||
state: Dep<rooms::state::Service>,
|
||||
state_cache: Dep<rooms::state_cache::Service>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Command {
|
||||
pub command: String,
|
||||
|
@ -58,12 +62,14 @@ impl crate::Service for Service {
|
|||
fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
||||
let (sender, receiver) = loole::bounded(COMMAND_QUEUE_LIMIT);
|
||||
Ok(Arc::new(Self {
|
||||
server: args.server.clone(),
|
||||
globals: args.require_service::<globals::Service>("globals"),
|
||||
alias: args.require_service::<rooms::alias::Service>("rooms::alias"),
|
||||
timeline: args.require_service::<rooms::timeline::Service>("rooms::timeline"),
|
||||
state: args.require_service::<rooms::state::Service>("rooms::state"),
|
||||
state_cache: args.require_service::<rooms::state_cache::Service>("rooms::state_cache"),
|
||||
services: Services {
|
||||
server: args.server.clone(),
|
||||
globals: args.depend::<globals::Service>("globals"),
|
||||
alias: args.depend::<rooms::alias::Service>("rooms::alias"),
|
||||
timeline: args.depend::<rooms::timeline::Service>("rooms::timeline"),
|
||||
state: args.depend::<rooms::state::Service>("rooms::state"),
|
||||
state_cache: args.depend::<rooms::state_cache::Service>("rooms::state_cache"),
|
||||
},
|
||||
sender,
|
||||
receiver: Mutex::new(receiver),
|
||||
handle: RwLock::new(None),
|
||||
|
@ -75,7 +81,7 @@ impl crate::Service for Service {
|
|||
|
||||
async fn worker(self: Arc<Self>) -> Result<()> {
|
||||
let receiver = self.receiver.lock().await;
|
||||
let mut signals = self.server.signal.subscribe();
|
||||
let mut signals = self.services.server.signal.subscribe();
|
||||
loop {
|
||||
tokio::select! {
|
||||
command = receiver.recv_async() => match command {
|
||||
|
@ -116,7 +122,7 @@ impl Service {
|
|||
|
||||
pub async fn send_message(&self, message_content: RoomMessageEventContent) {
|
||||
if let Ok(Some(room_id)) = self.get_admin_room() {
|
||||
let user_id = &self.globals.server_user;
|
||||
let user_id = &self.services.globals.server_user;
|
||||
self.respond_to_room(message_content, &room_id, user_id)
|
||||
.await;
|
||||
}
|
||||
|
@ -176,7 +182,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> {
|
||||
if let Ok(Some(admin_room)) = self.get_admin_room() {
|
||||
self.state_cache.is_joined(user_id, &admin_room)
|
||||
self.services.state_cache.is_joined(user_id, &admin_room)
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
|
@ -187,10 +193,15 @@ impl Service {
|
|||
/// Errors are propagated from the database, and will have None if there is
|
||||
/// no admin room
|
||||
pub fn get_admin_room(&self) -> Result<Option<OwnedRoomId>> {
|
||||
if let Some(room_id) = self.alias.resolve_local_alias(&self.globals.admin_alias)? {
|
||||
if let Some(room_id) = self
|
||||
.services
|
||||
.alias
|
||||
.resolve_local_alias(&self.services.globals.admin_alias)?
|
||||
{
|
||||
if self
|
||||
.services
|
||||
.state_cache
|
||||
.is_joined(&self.globals.server_user, &room_id)?
|
||||
.is_joined(&self.services.globals.server_user, &room_id)?
|
||||
{
|
||||
return Ok(Some(room_id));
|
||||
}
|
||||
|
@ -207,12 +218,12 @@ impl Service {
|
|||
return;
|
||||
};
|
||||
|
||||
let Ok(Some(pdu)) = self.timeline.get_pdu(&in_reply_to.event_id) else {
|
||||
let Ok(Some(pdu)) = self.services.timeline.get_pdu(&in_reply_to.event_id) else {
|
||||
return;
|
||||
};
|
||||
|
||||
let response_sender = if self.is_admin_room(&pdu.room_id) {
|
||||
&self.globals.server_user
|
||||
&self.services.globals.server_user
|
||||
} else {
|
||||
&pdu.sender
|
||||
};
|
||||
|
@ -229,7 +240,7 @@ impl Service {
|
|||
"sender is not admin"
|
||||
);
|
||||
|
||||
let state_lock = self.state.mutex.lock(room_id).await;
|
||||
let state_lock = self.services.state.mutex.lock(room_id).await;
|
||||
let response_pdu = PduBuilder {
|
||||
event_type: TimelineEventType::RoomMessage,
|
||||
content: to_raw_value(&content).expect("event is valid, we just created it"),
|
||||
|
@ -239,6 +250,7 @@ impl Service {
|
|||
};
|
||||
|
||||
if let Err(e) = self
|
||||
.services
|
||||
.timeline
|
||||
.build_and_append_pdu(response_pdu, user_id, room_id, &state_lock)
|
||||
.await
|
||||
|
@ -266,7 +278,8 @@ impl Service {
|
|||
redacts: None,
|
||||
};
|
||||
|
||||
self.timeline
|
||||
self.services
|
||||
.timeline
|
||||
.build_and_append_pdu(response_pdu, user_id, room_id, state_lock)
|
||||
.await?;
|
||||
|
||||
|
@ -279,7 +292,7 @@ impl Service {
|
|||
let is_public_escape = is_escape && body.trim_start_matches('\\').starts_with("!admin");
|
||||
|
||||
// Admin command with public echo (in admin room)
|
||||
let server_user = &self.globals.server_user;
|
||||
let server_user = &self.services.globals.server_user;
|
||||
let is_public_prefix = body.starts_with("!admin") || body.starts_with(server_user.as_str());
|
||||
|
||||
// Expected backward branch
|
||||
|
@ -293,7 +306,7 @@ impl Service {
|
|||
}
|
||||
|
||||
// Check if server-side command-escape is disabled by configuration
|
||||
if is_public_escape && !self.globals.config.admin_escape_commands {
|
||||
if is_public_escape && !self.services.globals.config.admin_escape_commands {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -309,7 +322,7 @@ impl Service {
|
|||
|
||||
// This will evaluate to false if the emergency password is set up so that
|
||||
// the administrator can execute commands as conduit
|
||||
let emergency_password_set = self.globals.emergency_password().is_some();
|
||||
let emergency_password_set = self.services.globals.emergency_password().is_some();
|
||||
let from_server = pdu.sender == *server_user && !emergency_password_set;
|
||||
if from_server && self.is_admin_room(&pdu.room_id) {
|
||||
return false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue