Refactor RegistrationInfo, fix #330

This commit is contained in:
dasha_uwu
2026-02-23 11:49:16 +05:00
parent 83a23e965b
commit d073e17f1a
3 changed files with 48 additions and 46 deletions

View File

@@ -1,4 +1,5 @@
use futures::StreamExt; use futures::StreamExt;
use ruma::api::appservice::Registration;
use tuwunel_core::{Err, Result, checked, err}; use tuwunel_core::{Err, Result, checked, err};
use crate::admin_command; use crate::admin_command;
@@ -16,18 +17,19 @@ pub(super) async fn appservice_register(&self) -> Result {
let range = 1..checked!(body_len - 1)?; let range = 1..checked!(body_len - 1)?;
let appservice_config_body = body[range].join("\n"); let appservice_config_body = body[range].join("\n");
let parsed_config = serde_yaml::from_str(&appservice_config_body);
let registration = let registration: Registration = serde_yaml::from_str(&appservice_config_body)
parsed_config.map_err(|e| err!("Could not parse appservice config as YAML: {e}"))?; .map_err(|e| err!("Could not parse appservice config as YAML: {e}"))?;
let id = registration.id.clone();
self.services self.services
.appservice .appservice
.register_appservice(&registration, &appservice_config_body) .register_appservice(registration)
.await .await
.map_err(|e| err!("Failed to register appservice: {e}"))?; .map_err(|e| err!("Failed to register appservice: {e}"))?;
self.write_str(&format!("Appservice registered with ID: {}", registration.id)) self.write_str(&format!("Appservice registered with ID: {}", &id))
.await .await
} }

View File

@@ -80,7 +80,10 @@ impl Service {
self.registration_info self.registration_info
.write() .write()
.await .await
.insert(id.clone(), reg.try_into()?) .insert(
id.clone(),
RegistrationInfo::new(reg, self.services.globals.server_name())?,
)
.map_or(Ok(()), |_| Err!("Conflicting Appservice ID: {id:?}")) .map_or(Ok(()), |_| Err!("Conflicting Appservice ID: {id:?}"))
}) })
.await .await
@@ -105,42 +108,36 @@ impl Service {
Ok(()) Ok(())
} }
/// Registers an appservice and returns the ID to the caller pub async fn register_appservice(&self, registration: Registration) -> Result {
pub async fn register_appservice( let appservice_yaml = serde_yaml::to_string(&registration)?;
&self,
registration: &Registration,
appservice_config_body: &str,
) -> Result {
let appservice_user = UserId::parse_with_server_name(
&registration.sender_localpart,
&self.services.config.server_name,
)?;
if !self.services.users.exists(&appservice_user).await { let id = registration.id.clone();
let registration_info =
RegistrationInfo::new(registration, self.services.globals.server_name())?;
let appservice_user = &registration_info.sender;
if !self.services.users.exists(appservice_user).await {
self.services self.services
.users .users
.create(&appservice_user, None, None) .create(appservice_user, None, None)
.await?; .await?;
} }
//TODO: Check for collisions between exclusive appservice namespaces //TODO: Check for collisions between exclusive appservice namespaces
self.db
.id_appserviceregistrations
.insert(&id, appservice_yaml);
self.registration_info self.registration_info
.write() .write()
.await .await
.insert(registration.id.clone(), registration.clone().try_into()?); .insert(id, registration_info);
self.db
.id_appserviceregistrations
.insert(&registration.id, appservice_config_body);
Ok(()) Ok(())
} }
/// Remove an appservice registration
///
/// # Arguments
///
/// * `service_name` - the registration ID of the appservice
pub async fn unregister_appservice(&self, appservice_id: &str) -> Result { pub async fn unregister_appservice(&self, appservice_id: &str) -> Result {
// removes the appservice registration info // removes the appservice registration info
self.registration_info self.registration_info

View File

@@ -1,4 +1,4 @@
use ruma::{UserId, api::appservice::Registration}; use ruma::{OwnedUserId, ServerName, UserId, api::appservice::Registration};
use tuwunel_core::Result; use tuwunel_core::Result;
use super::NamespaceRegex; use super::NamespaceRegex;
@@ -10,32 +10,35 @@ pub struct RegistrationInfo {
pub users: NamespaceRegex, pub users: NamespaceRegex,
pub aliases: NamespaceRegex, pub aliases: NamespaceRegex,
pub rooms: NamespaceRegex, pub rooms: NamespaceRegex,
pub sender: OwnedUserId,
} }
impl RegistrationInfo { impl RegistrationInfo {
pub fn new(registration: Registration, server_name: &ServerName) -> Result<Self> {
let sender =
OwnedUserId::parse(format!("@{}:{}", registration.sender_localpart, server_name))?;
Ok(Self {
users: registration.namespaces.users.clone().try_into()?,
aliases: registration
.namespaces
.aliases
.clone()
.try_into()?,
rooms: registration.namespaces.rooms.clone().try_into()?,
registration,
sender,
})
}
#[must_use] #[must_use]
pub fn is_user_match(&self, user_id: &UserId) -> bool { pub fn is_user_match(&self, user_id: &UserId) -> bool {
self.users.is_match(user_id.as_str()) user_id == self.sender || self.users.is_match(user_id.as_str())
|| self.registration.sender_localpart == user_id.localpart()
} }
#[inline] #[inline]
#[must_use] #[must_use]
pub fn is_exclusive_user_match(&self, user_id: &UserId) -> bool { pub fn is_exclusive_user_match(&self, user_id: &UserId) -> bool {
self.users.is_exclusive_match(user_id.as_str()) user_id == self.sender || self.users.is_exclusive_match(user_id.as_str())
|| self.registration.sender_localpart == user_id.localpart()
}
}
impl TryFrom<Registration> for RegistrationInfo {
type Error = regex::Error;
fn try_from(value: Registration) -> Result<Self, regex::Error> {
Ok(Self {
users: value.namespaces.users.clone().try_into()?,
aliases: value.namespaces.aliases.clone().try_into()?,
rooms: value.namespaces.rooms.clone().try_into()?,
registration: value,
})
} }
} }