Refactor RegistrationInfo, fix #330
This commit is contained in:
@@ -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(®istration, &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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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(®istration)?;
|
||||||
&self,
|
|
||||||
registration: &Registration,
|
|
||||||
appservice_config_body: &str,
|
|
||||||
) -> Result {
|
|
||||||
let appservice_user = UserId::parse_with_server_name(
|
|
||||||
®istration.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 = ®istration_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(®istration.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
|
||||||
|
|||||||
@@ -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,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user