revamp appservice registration to ruma's Registration type
squashed from https://gitlab.com/famedly/conduit/-/merge_requests/583 Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
parent
0e9eb22ee7
commit
784d307425
13 changed files with 203 additions and 208 deletions
|
@ -10,7 +10,7 @@ use std::fmt::Write;
|
|||
use clap::{Parser, Subcommand};
|
||||
use regex::Regex;
|
||||
use ruma::{
|
||||
api::client::error::ErrorKind,
|
||||
api::{appservice::Registration, client::error::ErrorKind},
|
||||
events::{
|
||||
relation::InReplyTo,
|
||||
room::{
|
||||
|
@ -472,7 +472,7 @@ impl Service {
|
|||
{
|
||||
let appservice_config = body[1..body.len() - 1].join("\n");
|
||||
let parsed_config =
|
||||
serde_yaml::from_str::<serde_yaml::Value>(&appservice_config);
|
||||
serde_yaml::from_str::<Registration>(&appservice_config);
|
||||
match parsed_config {
|
||||
Ok(yaml) => match services().appservice.register_appservice(yaml) {
|
||||
Ok(id) => RoomMessageEventContent::text_plain(format!(
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use ruma::api::appservice::Registration;
|
||||
|
||||
use crate::Result;
|
||||
|
||||
pub trait Data: Send + Sync {
|
||||
/// Registers an appservice and returns the ID to the caller
|
||||
fn register_appservice(&self, yaml: serde_yaml::Value) -> Result<String>;
|
||||
fn register_appservice(&self, yaml: Registration) -> Result<String>;
|
||||
|
||||
/// Remove an appservice registration
|
||||
///
|
||||
|
@ -11,9 +13,9 @@ pub trait Data: Send + Sync {
|
|||
/// * `service_name` - the name you send to register the service previously
|
||||
fn unregister_appservice(&self, service_name: &str) -> Result<()>;
|
||||
|
||||
fn get_registration(&self, id: &str) -> Result<Option<serde_yaml::Value>>;
|
||||
fn get_registration(&self, id: &str) -> Result<Option<Registration>>;
|
||||
|
||||
fn iter_ids<'a>(&'a self) -> Result<Box<dyn Iterator<Item = Result<String>> + 'a>>;
|
||||
|
||||
fn all(&self) -> Result<Vec<(String, serde_yaml::Value)>>;
|
||||
fn all(&self) -> Result<Vec<(String, Registration)>>;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
mod data;
|
||||
|
||||
pub(crate) use data::Data;
|
||||
use ruma::api::appservice::Registration;
|
||||
|
||||
use crate::Result;
|
||||
|
||||
|
@ -10,7 +11,7 @@ pub struct Service {
|
|||
|
||||
impl Service {
|
||||
/// Registers an appservice and returns the ID to the caller
|
||||
pub fn register_appservice(&self, yaml: serde_yaml::Value) -> Result<String> {
|
||||
pub fn register_appservice(&self, yaml: Registration) -> Result<String> {
|
||||
self.db.register_appservice(yaml)
|
||||
}
|
||||
|
||||
|
@ -23,7 +24,7 @@ impl Service {
|
|||
self.db.unregister_appservice(service_name)
|
||||
}
|
||||
|
||||
pub fn get_registration(&self, id: &str) -> Result<Option<serde_yaml::Value>> {
|
||||
pub fn get_registration(&self, id: &str) -> Result<Option<Registration>> {
|
||||
self.db.get_registration(id)
|
||||
}
|
||||
|
||||
|
@ -31,7 +32,7 @@ impl Service {
|
|||
self.db.iter_ids()
|
||||
}
|
||||
|
||||
pub fn all(&self) -> Result<Vec<(String, serde_yaml::Value)>> {
|
||||
pub fn all(&self) -> Result<Vec<(String, Registration)>> {
|
||||
self.db.all()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ use std::{collections::HashSet, sync::Arc};
|
|||
|
||||
use crate::Result;
|
||||
use ruma::{
|
||||
api::appservice::Registration,
|
||||
events::{AnyStrippedStateEvent, AnySyncStateEvent},
|
||||
serde::Raw,
|
||||
OwnedRoomId, OwnedServerName, OwnedUserId, RoomId, ServerName, UserId,
|
||||
|
@ -31,7 +32,7 @@ pub trait Data: Send + Sync {
|
|||
fn appservice_in_room(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
appservice: &(String, serde_yaml::Value),
|
||||
appservice: &(String, Registration),
|
||||
) -> Result<bool>;
|
||||
|
||||
/// Makes a user forget a room.
|
||||
|
|
|
@ -4,6 +4,7 @@ use std::{collections::HashSet, sync::Arc};
|
|||
pub use data::Data;
|
||||
|
||||
use ruma::{
|
||||
api::appservice::Registration,
|
||||
events::{
|
||||
direct::DirectEvent,
|
||||
ignored_user_list::IgnoredUserListEvent,
|
||||
|
@ -240,7 +241,7 @@ impl Service {
|
|||
pub fn appservice_in_room(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
appservice: &(String, serde_yaml::Value),
|
||||
appservice: &(String, Registration),
|
||||
) -> Result<bool> {
|
||||
self.db.appservice_in_room(room_id, appservice)
|
||||
}
|
||||
|
|
|
@ -621,73 +621,61 @@ impl Service {
|
|||
.as_ref()
|
||||
.and_then(|state_key| UserId::parse(state_key.as_str()).ok())
|
||||
{
|
||||
if let Some(appservice_uid) = appservice
|
||||
.1
|
||||
.get("sender_localpart")
|
||||
.and_then(|string| string.as_str())
|
||||
.and_then(|string| {
|
||||
UserId::parse_with_server_name(string, services().globals.server_name())
|
||||
.ok()
|
||||
})
|
||||
{
|
||||
if state_key_uid == &appservice_uid {
|
||||
services()
|
||||
.sending
|
||||
.send_pdu_appservice(appservice.0, pdu_id.clone())?;
|
||||
continue;
|
||||
}
|
||||
let appservice_uid = appservice.1.sender_localpart.as_str();
|
||||
if state_key_uid == appservice_uid {
|
||||
services()
|
||||
.sending
|
||||
.send_pdu_appservice(appservice.0, pdu_id.clone())?;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(namespaces) = appservice.1.get("namespaces") {
|
||||
let users = namespaces
|
||||
.get("users")
|
||||
.and_then(|users| users.as_sequence())
|
||||
.map_or_else(Vec::new, |users| {
|
||||
users
|
||||
.iter()
|
||||
.filter_map(|users| Regex::new(users.get("regex")?.as_str()?).ok())
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
let aliases = namespaces
|
||||
.get("aliases")
|
||||
.and_then(|aliases| aliases.as_sequence())
|
||||
.map_or_else(Vec::new, |aliases| {
|
||||
aliases
|
||||
.iter()
|
||||
.filter_map(|aliases| Regex::new(aliases.get("regex")?.as_str()?).ok())
|
||||
.collect::<Vec<_>>()
|
||||
});
|
||||
let rooms = namespaces
|
||||
.get("rooms")
|
||||
.and_then(|rooms| rooms.as_sequence());
|
||||
let namespaces = appservice.1.namespaces;
|
||||
|
||||
let matching_users = |users: &Regex| {
|
||||
users.is_match(pdu.sender.as_str())
|
||||
|| pdu.kind == TimelineEventType::RoomMember
|
||||
&& pdu
|
||||
.state_key
|
||||
.as_ref()
|
||||
.map_or(false, |state_key| users.is_match(state_key))
|
||||
};
|
||||
let matching_aliases = |aliases: &Regex| {
|
||||
services()
|
||||
.rooms
|
||||
.alias
|
||||
.local_aliases_for_room(&pdu.room_id)
|
||||
.filter_map(|r| r.ok())
|
||||
.any(|room_alias| aliases.is_match(room_alias.as_str()))
|
||||
};
|
||||
// TODO: create some helper function to change from Strings to Regexes
|
||||
let users = namespaces
|
||||
.users
|
||||
.iter()
|
||||
.filter_map(|user| Regex::new(user.regex.as_str()).ok())
|
||||
.collect::<Vec<_>>();
|
||||
let aliases = namespaces
|
||||
.aliases
|
||||
.iter()
|
||||
.filter_map(|alias| Regex::new(alias.regex.as_str()).ok())
|
||||
.collect::<Vec<_>>();
|
||||
let rooms = namespaces
|
||||
.rooms
|
||||
.iter()
|
||||
.filter_map(|room| Regex::new(room.regex.as_str()).ok())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if aliases.iter().any(matching_aliases)
|
||||
|| rooms.map_or(false, |rooms| rooms.contains(&pdu.room_id.as_str().into()))
|
||||
|| users.iter().any(matching_users)
|
||||
{
|
||||
services()
|
||||
.sending
|
||||
.send_pdu_appservice(appservice.0, pdu_id.clone())?;
|
||||
}
|
||||
let matching_users = |users: &Regex| {
|
||||
users.is_match(pdu.sender.as_str())
|
||||
|| pdu.kind == TimelineEventType::RoomMember
|
||||
&& pdu
|
||||
.state_key
|
||||
.as_ref()
|
||||
.map_or(false, |state_key| users.is_match(state_key))
|
||||
};
|
||||
let matching_aliases = |aliases: &Regex| {
|
||||
services()
|
||||
.rooms
|
||||
.alias
|
||||
.local_aliases_for_room(&pdu.room_id)
|
||||
.filter_map(|r| r.ok())
|
||||
.any(|room_alias| aliases.is_match(room_alias.as_str()))
|
||||
};
|
||||
|
||||
if aliases.iter().any(matching_aliases)
|
||||
|| rooms
|
||||
.iter()
|
||||
.any(|namespace| namespace.is_match(pdu.room_id.as_str()))
|
||||
|| users.iter().any(matching_users)
|
||||
{
|
||||
services()
|
||||
.sending
|
||||
.send_pdu_appservice(appservice.0, pdu_id.clone())?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ use base64::{engine::general_purpose, Engine as _};
|
|||
|
||||
use ruma::{
|
||||
api::{
|
||||
appservice,
|
||||
appservice::{self, Registration},
|
||||
federation::{
|
||||
self,
|
||||
transactions::edu::{
|
||||
|
@ -520,7 +520,7 @@ impl Service {
|
|||
|
||||
let permit = services().sending.maximum_requests.acquire().await;
|
||||
|
||||
let response = appservice_server::send_request(
|
||||
let response = match appservice_server::send_request(
|
||||
services()
|
||||
.appservice
|
||||
.get_registration(id)
|
||||
|
@ -547,8 +547,12 @@ impl Service {
|
|||
},
|
||||
)
|
||||
.await
|
||||
.map(|_response| kind.clone())
|
||||
.map_err(|e| (kind, e));
|
||||
{
|
||||
None => Ok(kind.clone()),
|
||||
Some(op_resp) => op_resp
|
||||
.map(|_response| kind.clone())
|
||||
.map_err(|e| (kind.clone(), e)),
|
||||
};
|
||||
|
||||
drop(permit);
|
||||
|
||||
|
@ -764,12 +768,14 @@ impl Service {
|
|||
response
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self, registration, request))]
|
||||
/// Sends a request to an appservice
|
||||
///
|
||||
/// Only returns None if there is no url specified in the appservice registration file
|
||||
pub async fn send_appservice_request<T: OutgoingRequest>(
|
||||
&self,
|
||||
registration: serde_yaml::Value,
|
||||
registration: Registration,
|
||||
request: T,
|
||||
) -> Result<T::IncomingResponse>
|
||||
) -> Option<Result<T::IncomingResponse>>
|
||||
where
|
||||
T: Debug,
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue