fix(appservices): don't panic on empty registration url
perf(appservices): cache regex for namespaces
This commit is contained in:
parent
a095e02d04
commit
fa930182ae
15 changed files with 335 additions and 244 deletions
|
@ -7,7 +7,7 @@ use std::{
|
|||
};
|
||||
|
||||
pub use data::Data;
|
||||
use regex::Regex;
|
||||
|
||||
use ruma::{
|
||||
api::{client::error::ErrorKind, federation},
|
||||
canonical_json::to_canonical_value,
|
||||
|
@ -21,8 +21,7 @@ use ruma::{
|
|||
},
|
||||
push::{Action, Ruleset, Tweak},
|
||||
serde::Base64,
|
||||
state_res,
|
||||
state_res::{Event, RoomVersion},
|
||||
state_res::{self, Event, RoomVersion},
|
||||
uint, user_id, CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId,
|
||||
OwnedServerName, RoomId, ServerName, UserId,
|
||||
};
|
||||
|
@ -33,7 +32,10 @@ use tracing::{error, info, warn};
|
|||
|
||||
use crate::{
|
||||
api::server_server,
|
||||
service::pdu::{EventHash, PduBuilder},
|
||||
service::{
|
||||
appservice::NamespaceRegex,
|
||||
pdu::{EventHash, PduBuilder},
|
||||
},
|
||||
services, utils, Error, PduEvent, Result,
|
||||
};
|
||||
|
||||
|
@ -522,15 +524,21 @@ impl Service {
|
|||
}
|
||||
}
|
||||
|
||||
for appservice in services().appservice.all()? {
|
||||
for appservice in services()
|
||||
.appservice
|
||||
.registration_info
|
||||
.read()
|
||||
.await
|
||||
.values()
|
||||
{
|
||||
if services()
|
||||
.rooms
|
||||
.state_cache
|
||||
.appservice_in_room(&pdu.room_id, &appservice)?
|
||||
.appservice_in_room(&pdu.room_id, appservice)?
|
||||
{
|
||||
services()
|
||||
.sending
|
||||
.send_pdu_appservice(appservice.0, pdu_id.clone())?;
|
||||
.send_pdu_appservice(appservice.registration.id.clone(), pdu_id.clone())?;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -542,73 +550,41 @@ 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.registration.sender_localpart.as_str();
|
||||
if state_key_uid == appservice_uid {
|
||||
services().sending.send_pdu_appservice(
|
||||
appservice.registration.id.clone(),
|
||||
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 matching_users = |users: &NamespaceRegex| {
|
||||
appservice.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: &NamespaceRegex| {
|
||||
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()))
|
||||
};
|
||||
|
||||
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.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())?;
|
||||
}
|
||||
if matching_aliases(&appservice.aliases)
|
||||
|| appservice.rooms.is_match(pdu.room_id.as_str())
|
||||
|| matching_users(&appservice.users)
|
||||
{
|
||||
services()
|
||||
.sending
|
||||
.send_pdu_appservice(appservice.registration.id.clone(), pdu_id.clone())?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue