Refactor RegistrationInfo, fix #330
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use futures::StreamExt;
|
||||
use ruma::api::appservice::Registration;
|
||||
use tuwunel_core::{Err, Result, checked, err};
|
||||
|
||||
use crate::admin_command;
|
||||
@@ -16,18 +17,19 @@ pub(super) async fn appservice_register(&self) -> Result {
|
||||
|
||||
let range = 1..checked!(body_len - 1)?;
|
||||
let appservice_config_body = body[range].join("\n");
|
||||
let parsed_config = serde_yaml::from_str(&appservice_config_body);
|
||||
|
||||
let registration =
|
||||
parsed_config.map_err(|e| err!("Could not parse appservice config as YAML: {e}"))?;
|
||||
let registration: Registration = serde_yaml::from_str(&appservice_config_body)
|
||||
.map_err(|e| err!("Could not parse appservice config as YAML: {e}"))?;
|
||||
|
||||
let id = registration.id.clone();
|
||||
|
||||
self.services
|
||||
.appservice
|
||||
.register_appservice(®istration, &appservice_config_body)
|
||||
.register_appservice(registration)
|
||||
.await
|
||||
.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
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,10 @@ impl Service {
|
||||
self.registration_info
|
||||
.write()
|
||||
.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:?}"))
|
||||
})
|
||||
.await
|
||||
@@ -105,42 +108,36 @@ impl Service {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Registers an appservice and returns the ID to the caller
|
||||
pub async fn register_appservice(
|
||||
&self,
|
||||
registration: &Registration,
|
||||
appservice_config_body: &str,
|
||||
) -> Result {
|
||||
let appservice_user = UserId::parse_with_server_name(
|
||||
®istration.sender_localpart,
|
||||
&self.services.config.server_name,
|
||||
)?;
|
||||
pub async fn register_appservice(&self, registration: Registration) -> Result {
|
||||
let appservice_yaml = serde_yaml::to_string(®istration)?;
|
||||
|
||||
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 = ®istration_info.sender;
|
||||
|
||||
if !self.services.users.exists(appservice_user).await {
|
||||
self.services
|
||||
.users
|
||||
.create(&appservice_user, None, None)
|
||||
.create(appservice_user, None, None)
|
||||
.await?;
|
||||
}
|
||||
|
||||
//TODO: Check for collisions between exclusive appservice namespaces
|
||||
self.db
|
||||
.id_appserviceregistrations
|
||||
.insert(&id, appservice_yaml);
|
||||
|
||||
self.registration_info
|
||||
.write()
|
||||
.await
|
||||
.insert(registration.id.clone(), registration.clone().try_into()?);
|
||||
|
||||
self.db
|
||||
.id_appserviceregistrations
|
||||
.insert(®istration.id, appservice_config_body);
|
||||
.insert(id, registration_info);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Remove an appservice registration
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `service_name` - the registration ID of the appservice
|
||||
pub async fn unregister_appservice(&self, appservice_id: &str) -> Result {
|
||||
// removes the appservice registration info
|
||||
self.registration_info
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use ruma::{UserId, api::appservice::Registration};
|
||||
use ruma::{OwnedUserId, ServerName, UserId, api::appservice::Registration};
|
||||
use tuwunel_core::Result;
|
||||
|
||||
use super::NamespaceRegex;
|
||||
@@ -10,32 +10,35 @@ pub struct RegistrationInfo {
|
||||
pub users: NamespaceRegex,
|
||||
pub aliases: NamespaceRegex,
|
||||
pub rooms: NamespaceRegex,
|
||||
pub sender: OwnedUserId,
|
||||
}
|
||||
|
||||
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]
|
||||
pub fn is_user_match(&self, user_id: &UserId) -> bool {
|
||||
self.users.is_match(user_id.as_str())
|
||||
|| self.registration.sender_localpart == user_id.localpart()
|
||||
user_id == self.sender || self.users.is_match(user_id.as_str())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn is_exclusive_user_match(&self, user_id: &UserId) -> bool {
|
||||
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,
|
||||
})
|
||||
user_id == self.sender || self.users.is_exclusive_match(user_id.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user