messing with trait objects
This commit is contained in:
parent
8708cd3b63
commit
face766e0f
61 changed files with 623 additions and 544 deletions
|
@ -17,11 +17,11 @@ use tracing::error;
|
|||
|
||||
use crate::{service::*, services, utils, Error, Result};
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
/// Places one event in the account data of the user and removes the previous entry.
|
||||
#[tracing::instrument(skip(self, room_id, user_id, event_type, data))]
|
||||
pub fn update<T: Serialize>(
|
||||
|
|
|
@ -3,11 +3,11 @@ pub use data::Data;
|
|||
|
||||
use crate::Result;
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
/// Registers an appservice and returns the ID to the caller
|
||||
pub fn register_appservice(&self, yaml: serde_yaml::Value) -> Result<String> {
|
||||
self.db.register_appservice(yaml)
|
||||
|
|
|
@ -36,8 +36,8 @@ type SyncHandle = (
|
|||
Receiver<Option<Result<sync_events::v3::Response>>>, // rx
|
||||
);
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
pub db: D,
|
||||
pub struct Service {
|
||||
pub db: Box<dyn Data>,
|
||||
|
||||
pub actual_destination_cache: Arc<RwLock<WellKnownMap>>, // actual_destination, host
|
||||
pub tls_name_override: Arc<RwLock<TlsNameMap>>,
|
||||
|
@ -92,9 +92,9 @@ impl Default for RotationHandler {
|
|||
}
|
||||
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
pub fn load(
|
||||
db: D,
|
||||
db: Box<dyn Data>,
|
||||
config: Config,
|
||||
) -> Result<Self> {
|
||||
let keypair = db.load_keypair();
|
||||
|
|
|
@ -12,11 +12,11 @@ use ruma::{
|
|||
};
|
||||
use std::{collections::BTreeMap, sync::Arc};
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
pub fn create_backup(
|
||||
&self,
|
||||
user_id: &UserId,
|
||||
|
|
|
@ -15,11 +15,11 @@ pub struct FileMeta {
|
|||
pub file: Vec<u8>,
|
||||
}
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
/// Uploads a file.
|
||||
pub async fn create(
|
||||
&self,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
pub mod account_data;
|
||||
pub mod admin;
|
||||
pub mod appservice;
|
||||
|
@ -12,18 +14,36 @@ pub mod transaction_ids;
|
|||
pub mod uiaa;
|
||||
pub mod users;
|
||||
|
||||
pub struct Services<D: appservice::Data + pusher::Data + rooms::Data + transaction_ids::Data + uiaa::Data + users::Data + account_data::Data + globals::Data + key_backups::Data + media::Data>
|
||||
{
|
||||
pub appservice: appservice::Service<D>,
|
||||
pub pusher: pusher::Service<D>,
|
||||
pub rooms: rooms::Service<D>,
|
||||
pub transaction_ids: transaction_ids::Service<D>,
|
||||
pub uiaa: uiaa::Service<D>,
|
||||
pub users: users::Service<D>,
|
||||
pub account_data: account_data::Service<D>,
|
||||
pub struct Services {
|
||||
pub appservice: appservice::Service,
|
||||
pub pusher: pusher::Service,
|
||||
pub rooms: rooms::Service,
|
||||
pub transaction_ids: transaction_ids::Service,
|
||||
pub uiaa: uiaa::Service,
|
||||
pub users: users::Service,
|
||||
pub account_data: account_data::Service,
|
||||
pub admin: admin::Service,
|
||||
pub globals: globals::Service<D>,
|
||||
pub key_backups: key_backups::Service<D>,
|
||||
pub media: media::Service<D>,
|
||||
pub globals: globals::Service,
|
||||
pub key_backups: key_backups::Service,
|
||||
pub media: media::Service,
|
||||
pub sending: sending::Service,
|
||||
}
|
||||
|
||||
impl Services {
|
||||
pub fn build<D: appservice::Data + pusher::Data + rooms::Data + transaction_ids::Data + uiaa::Data + users::Data + account_data::Data + globals::Data + key_backups::Data + media::Data>(db: Arc<D>) {
|
||||
Self {
|
||||
appservice: appservice::Service { db: Arc::clone(&db) },
|
||||
pusher: appservice::Service { db: Arc::clone(&db) },
|
||||
rooms: appservice::Service { db: Arc::clone(&db) },
|
||||
transaction_ids: appservice::Service { db: Arc::clone(&db) },
|
||||
uiaa: appservice::Service { db: Arc::clone(&db) },
|
||||
users: appservice::Service { db: Arc::clone(&db) },
|
||||
account_data: appservice::Service { db: Arc::clone(&db) },
|
||||
admin: appservice::Service { db: Arc::clone(&db) },
|
||||
globals: appservice::Service { db: Arc::clone(&db) },
|
||||
key_backups: appservice::Service { db: Arc::clone(&db) },
|
||||
media: appservice::Service { db: Arc::clone(&db) },
|
||||
sending: appservice::Service { db: Arc::clone(&db) },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,11 +23,11 @@ use ruma::{
|
|||
use std::{fmt::Debug, mem};
|
||||
use tracing::{error, info, warn};
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
pub fn set_pusher(&self, sender: &UserId, pusher: set_pusher::v3::Pusher) -> Result<()> {
|
||||
self.db.set_pusher(sender, pusher)
|
||||
}
|
||||
|
|
|
@ -25,5 +25,5 @@ pub trait Data {
|
|||
fn local_aliases_for_room(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
) -> Result<Box<dyn Iterator<Item=String>>>;
|
||||
) -> Box<dyn Iterator<Item = Result<Box<RoomAliasId>>>>;
|
||||
}
|
||||
|
|
|
@ -4,11 +4,11 @@ pub use data::Data;
|
|||
use ruma::{RoomAliasId, RoomId};
|
||||
use crate::Result;
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn set_alias(
|
||||
&self,
|
||||
|
|
|
@ -2,6 +2,6 @@ use std::collections::HashSet;
|
|||
use crate::Result;
|
||||
|
||||
pub trait Data {
|
||||
fn get_cached_eventid_authchain(&self, shorteventid: u64) -> Result<HashSet<u64>>;
|
||||
fn get_cached_eventid_authchain(&self, shorteventid: u64) -> Result<Option<HashSet<u64>>>;
|
||||
fn cache_eventid_authchain(&self, shorteventid: u64, auth_chain: &HashSet<u64>) -> Result<()>;
|
||||
}
|
||||
|
|
|
@ -5,11 +5,11 @@ pub use data::Data;
|
|||
|
||||
use crate::Result;
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn get_cached_eventid_authchain<'a>(
|
||||
&'a self,
|
||||
|
|
|
@ -4,11 +4,11 @@ use ruma::RoomId;
|
|||
|
||||
use crate::Result;
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn set_public(&self, room_id: &RoomId) -> Result<()> {
|
||||
self.db.set_public(room_id)
|
||||
|
|
|
@ -4,8 +4,8 @@ pub mod typing;
|
|||
|
||||
pub trait Data: presence::Data + read_receipt::Data + typing::Data {}
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
pub presence: presence::Service<D>,
|
||||
pub read_receipt: read_receipt::Service<D>,
|
||||
pub typing: typing::Service<D>,
|
||||
pub struct Service {
|
||||
pub presence: presence::Service,
|
||||
pub read_receipt: read_receipt::Service,
|
||||
pub typing: typing::Service,
|
||||
}
|
||||
|
|
|
@ -6,11 +6,11 @@ use ruma::{RoomId, UserId, events::presence::PresenceEvent};
|
|||
|
||||
use crate::Result;
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
/// Adds a presence event which will be saved until a new event replaces it.
|
||||
///
|
||||
/// Note: This method takes a RoomId because presence updates are always bound to rooms to
|
||||
|
|
|
@ -4,11 +4,11 @@ pub use data::Data;
|
|||
use ruma::{RoomId, UserId, events::receipt::ReceiptEvent, serde::Raw};
|
||||
use crate::Result;
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
/// Replaces the previous read receipt.
|
||||
pub fn readreceipt_update(
|
||||
&self,
|
||||
|
|
|
@ -4,11 +4,11 @@ use ruma::{UserId, RoomId, events::SyncEphemeralRoomEvent};
|
|||
|
||||
use crate::Result;
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
/// Sets a user as typing until the timeout timestamp is reached or roomtyping_remove is
|
||||
/// called.
|
||||
pub fn typing_add(&self, user_id: &UserId, room_id: &RoomId, timeout: u64) -> Result<()> {
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
/// An async function that can recursively call itself.
|
||||
type AsyncRecursiveType<'a, T> = Pin<Box<dyn Future<Output = T> + 'a + Send>>;
|
||||
|
||||
use ruma::{RoomVersionId, signatures::CanonicalJsonObject, api::federation::discovery::{get_server_keys, get_remote_server_keys}};
|
||||
use tokio::sync::Semaphore;
|
||||
use std::{
|
||||
collections::{btree_map, hash_map, BTreeMap, HashMap, HashSet},
|
||||
pin::Pin,
|
||||
sync::{Arc, RwLock},
|
||||
time::{Duration, Instant},
|
||||
sync::{Arc, RwLock, RwLockWriteGuard},
|
||||
time::{Duration, Instant, SystemTime},
|
||||
};
|
||||
|
||||
use futures_util::{Future, stream::FuturesUnordered};
|
||||
use futures_util::{Future, stream::FuturesUnordered, StreamExt};
|
||||
use ruma::{
|
||||
api::{
|
||||
client::error::ErrorKind,
|
||||
|
@ -22,7 +24,7 @@ use ruma::{
|
|||
uint, EventId, MilliSecondsSinceUnixEpoch, RoomId, ServerName, ServerSigningKeyId,
|
||||
};
|
||||
use serde_json::value::{to_raw_value, RawValue as RawJsonValue};
|
||||
use tracing::{error, info, trace, warn};
|
||||
use tracing::{error, info, trace, warn, debug};
|
||||
|
||||
use crate::{service::*, services, Result, Error, PduEvent};
|
||||
|
||||
|
@ -53,7 +55,7 @@ impl Service {
|
|||
/// it
|
||||
/// 14. Use state resolution to find new room state
|
||||
// We use some AsyncRecursiveType hacks here so we can call this async funtion recursively
|
||||
#[tracing::instrument(skip(value, is_timeline_event, pub_key_map))]
|
||||
#[tracing::instrument(skip(self, value, is_timeline_event, pub_key_map))]
|
||||
pub(crate) async fn handle_incoming_pdu<'a>(
|
||||
&self,
|
||||
origin: &'a ServerName,
|
||||
|
@ -64,10 +66,11 @@ impl Service {
|
|||
pub_key_map: &'a RwLock<BTreeMap<String, BTreeMap<String, Base64>>>,
|
||||
) -> Result<Option<Vec<u8>>> {
|
||||
if !services().rooms.metadata.exists(room_id)? {
|
||||
return Error::BadRequest(
|
||||
return Err(Error::BadRequest(
|
||||
ErrorKind::NotFound,
|
||||
"Room is unknown to this server",
|
||||
)};
|
||||
));
|
||||
}
|
||||
|
||||
services()
|
||||
.rooms
|
||||
|
@ -732,7 +735,7 @@ impl Service {
|
|||
&incoming_pdu.sender,
|
||||
incoming_pdu.state_key.as_deref(),
|
||||
&incoming_pdu.content,
|
||||
)?
|
||||
)?;
|
||||
|
||||
let soft_fail = !state_res::event_auth::auth_check(
|
||||
&room_version,
|
||||
|
@ -821,7 +824,7 @@ impl Service {
|
|||
let shortstatekey = services()
|
||||
.rooms
|
||||
.short
|
||||
.get_or_create_shortstatekey(&incoming_pdu.kind.to_string().into(), state_key)?
|
||||
.get_or_create_shortstatekey(&incoming_pdu.kind.to_string().into(), state_key)?;
|
||||
|
||||
state_after.insert(shortstatekey, Arc::from(&*incoming_pdu.event_id));
|
||||
}
|
||||
|
@ -1236,7 +1239,7 @@ impl Service {
|
|||
|
||||
let signature_ids = signature_object.keys().cloned().collect::<Vec<_>>();
|
||||
|
||||
let fetch_res = fetch_signing_keys(
|
||||
let fetch_res = self.fetch_signing_keys(
|
||||
signature_server.as_str().try_into().map_err(|_| {
|
||||
Error::BadServerResponse("Invalid servername in signatures of server response pdu.")
|
||||
})?,
|
||||
|
@ -1481,4 +1484,168 @@ impl Service {
|
|||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// Search the DB for the signing keys of the given server, if we don't have them
|
||||
/// fetch them from the server and save to our DB.
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub async fn fetch_signing_keys(
|
||||
&self,
|
||||
origin: &ServerName,
|
||||
signature_ids: Vec<String>,
|
||||
) -> Result<BTreeMap<String, Base64>> {
|
||||
let contains_all_ids =
|
||||
|keys: &BTreeMap<String, Base64>| signature_ids.iter().all(|id| keys.contains_key(id));
|
||||
|
||||
let permit = services()
|
||||
.globals
|
||||
.servername_ratelimiter
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(origin)
|
||||
.map(|s| Arc::clone(s).acquire_owned());
|
||||
|
||||
let permit = match permit {
|
||||
Some(p) => p,
|
||||
None => {
|
||||
let mut write = services().globals.servername_ratelimiter.write().unwrap();
|
||||
let s = Arc::clone(
|
||||
write
|
||||
.entry(origin.to_owned())
|
||||
.or_insert_with(|| Arc::new(Semaphore::new(1))),
|
||||
);
|
||||
|
||||
s.acquire_owned()
|
||||
}
|
||||
}
|
||||
.await;
|
||||
|
||||
let back_off = |id| match services()
|
||||
.globals
|
||||
.bad_signature_ratelimiter
|
||||
.write()
|
||||
.unwrap()
|
||||
.entry(id)
|
||||
{
|
||||
hash_map::Entry::Vacant(e) => {
|
||||
e.insert((Instant::now(), 1));
|
||||
}
|
||||
hash_map::Entry::Occupied(mut e) => *e.get_mut() = (Instant::now(), e.get().1 + 1),
|
||||
};
|
||||
|
||||
if let Some((time, tries)) = services()
|
||||
.globals
|
||||
.bad_signature_ratelimiter
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(&signature_ids)
|
||||
{
|
||||
// Exponential backoff
|
||||
let mut min_elapsed_duration = Duration::from_secs(30) * (*tries) * (*tries);
|
||||
if min_elapsed_duration > Duration::from_secs(60 * 60 * 24) {
|
||||
min_elapsed_duration = Duration::from_secs(60 * 60 * 24);
|
||||
}
|
||||
|
||||
if time.elapsed() < min_elapsed_duration {
|
||||
debug!("Backing off from {:?}", signature_ids);
|
||||
return Err(Error::BadServerResponse("bad signature, still backing off"));
|
||||
}
|
||||
}
|
||||
|
||||
trace!("Loading signing keys for {}", origin);
|
||||
|
||||
let mut result: BTreeMap<_, _> = services()
|
||||
.globals
|
||||
.signing_keys_for(origin)?
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k.to_string(), v.key))
|
||||
.collect();
|
||||
|
||||
if contains_all_ids(&result) {
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
debug!("Fetching signing keys for {} over federation", origin);
|
||||
|
||||
if let Some(server_key) = services()
|
||||
.sending
|
||||
.send_federation_request(origin, get_server_keys::v2::Request::new())
|
||||
.await
|
||||
.ok()
|
||||
.and_then(|resp| resp.server_key.deserialize().ok())
|
||||
{
|
||||
services().globals.add_signing_key(origin, server_key.clone())?;
|
||||
|
||||
result.extend(
|
||||
server_key
|
||||
.verify_keys
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k.to_string(), v.key)),
|
||||
);
|
||||
result.extend(
|
||||
server_key
|
||||
.old_verify_keys
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k.to_string(), v.key)),
|
||||
);
|
||||
|
||||
if contains_all_ids(&result) {
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
||||
|
||||
for server in services().globals.trusted_servers() {
|
||||
debug!("Asking {} for {}'s signing key", server, origin);
|
||||
if let Some(server_keys) = services()
|
||||
.sending
|
||||
.send_federation_request(
|
||||
server,
|
||||
get_remote_server_keys::v2::Request::new(
|
||||
origin,
|
||||
MilliSecondsSinceUnixEpoch::from_system_time(
|
||||
SystemTime::now()
|
||||
.checked_add(Duration::from_secs(3600))
|
||||
.expect("SystemTime to large"),
|
||||
)
|
||||
.expect("time is valid"),
|
||||
),
|
||||
)
|
||||
.await
|
||||
.ok()
|
||||
.map(|resp| {
|
||||
resp.server_keys
|
||||
.into_iter()
|
||||
.filter_map(|e| e.deserialize().ok())
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
{
|
||||
trace!("Got signing keys: {:?}", server_keys);
|
||||
for k in server_keys {
|
||||
services().globals.add_signing_key(origin, k.clone())?;
|
||||
result.extend(
|
||||
k.verify_keys
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k.to_string(), v.key)),
|
||||
);
|
||||
result.extend(
|
||||
k.old_verify_keys
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k.to_string(), v.key)),
|
||||
);
|
||||
}
|
||||
|
||||
if contains_all_ids(&result) {
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drop(permit);
|
||||
|
||||
back_off(signature_ids);
|
||||
|
||||
warn!("Failed to find public key for server: {}", origin);
|
||||
Err(Error::BadServerResponse(
|
||||
"Failed to find public key for server",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ pub trait Data {
|
|||
user_id: &UserId,
|
||||
device_id: &DeviceId,
|
||||
room_id: &RoomId,
|
||||
since: u64,
|
||||
confirmed_user_ids: &mut dyn Iterator<Item=&UserId>,
|
||||
) -> Result<()>;
|
||||
|
||||
fn lazy_load_reset(
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
mod data;
|
||||
use std::collections::HashSet;
|
||||
use std::{collections::{HashSet, HashMap}, sync::Mutex};
|
||||
|
||||
pub use data::Data;
|
||||
use ruma::{DeviceId, UserId, RoomId};
|
||||
|
||||
use crate::Result;
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
|
||||
lazy_load_waiting: Mutex<HashMap<(Box<UserId>, Box<DeviceId>, Box<RoomId>, u64), HashSet<Box<UserId>>>>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn lazy_load_was_sent_before(
|
||||
&self,
|
||||
|
@ -50,7 +52,18 @@ impl<D: Data> Service<D> {
|
|||
room_id: &RoomId,
|
||||
since: u64,
|
||||
) -> Result<()> {
|
||||
self.db.lazy_load_confirm_delivery(user_id, device_id, room_id, since)
|
||||
if let Some(user_ids) = self.lazy_load_waiting.lock().unwrap().remove(&(
|
||||
user_id.to_owned(),
|
||||
device_id.to_owned(),
|
||||
room_id.to_owned(),
|
||||
since,
|
||||
)) {
|
||||
self.db.lazy_load_confirm_delivery(user_id, device_id, room_id, &mut user_ids.iter().map(|&u| &*u))?;
|
||||
} else {
|
||||
// Ignore
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
|
|
|
@ -4,11 +4,11 @@ use ruma::RoomId;
|
|||
|
||||
use crate::Result;
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
/// Checks if a room exists.
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn exists(&self, room_id: &RoomId) -> Result<bool> {
|
||||
|
|
|
@ -18,22 +18,22 @@ pub mod user;
|
|||
|
||||
pub trait Data: alias::Data + auth_chain::Data + directory::Data + edus::Data + lazy_loading::Data + metadata::Data + outlier::Data + pdu_metadata::Data + search::Data + short::Data + state::Data + state_accessor::Data + state_cache::Data + state_compressor::Data + timeline::Data + user::Data {}
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
pub alias: alias::Service<D>,
|
||||
pub auth_chain: auth_chain::Service<D>,
|
||||
pub directory: directory::Service<D>,
|
||||
pub edus: edus::Service<D>,
|
||||
pub struct Service {
|
||||
pub alias: alias::Service,
|
||||
pub auth_chain: auth_chain::Service,
|
||||
pub directory: directory::Service,
|
||||
pub edus: edus::Service,
|
||||
pub event_handler: event_handler::Service,
|
||||
pub lazy_loading: lazy_loading::Service<D>,
|
||||
pub metadata: metadata::Service<D>,
|
||||
pub outlier: outlier::Service<D>,
|
||||
pub pdu_metadata: pdu_metadata::Service<D>,
|
||||
pub search: search::Service<D>,
|
||||
pub short: short::Service<D>,
|
||||
pub state: state::Service<D>,
|
||||
pub state_accessor: state_accessor::Service<D>,
|
||||
pub state_cache: state_cache::Service<D>,
|
||||
pub state_compressor: state_compressor::Service<D>,
|
||||
pub timeline: timeline::Service<D>,
|
||||
pub user: user::Service<D>,
|
||||
pub lazy_loading: lazy_loading::Service,
|
||||
pub metadata: metadata::Service,
|
||||
pub outlier: outlier::Service,
|
||||
pub pdu_metadata: pdu_metadata::Service,
|
||||
pub search: search::Service,
|
||||
pub short: short::Service,
|
||||
pub state: state::Service,
|
||||
pub state_accessor: state_accessor::Service,
|
||||
pub state_cache: state_cache::Service,
|
||||
pub state_compressor: state_compressor::Service,
|
||||
pub timeline: timeline::Service,
|
||||
pub user: user::Service,
|
||||
}
|
||||
|
|
|
@ -4,11 +4,11 @@ use ruma::{EventId, signatures::CanonicalJsonObject};
|
|||
|
||||
use crate::{Result, PduEvent};
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
/// Returns the pdu from the outlier tree.
|
||||
pub fn get_outlier_pdu_json(&self, event_id: &EventId) -> Result<Option<CanonicalJsonObject>> {
|
||||
self.db.get_outlier_pdu_json(event_id)
|
||||
|
|
|
@ -6,11 +6,11 @@ use ruma::{RoomId, EventId};
|
|||
|
||||
use crate::Result;
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
#[tracing::instrument(skip(self, room_id, event_ids))]
|
||||
pub fn mark_as_referenced(&self, room_id: &RoomId, event_ids: &[Arc<EventId>]) -> Result<()> {
|
||||
self.db.mark_as_referenced(room_id, event_ids)
|
||||
|
|
|
@ -2,7 +2,7 @@ use ruma::RoomId;
|
|||
use crate::Result;
|
||||
|
||||
pub trait Data {
|
||||
fn index_pdu<'a>(&self, shortroomid: u64, pdu_id: u64, message_body: String) -> Result<()>;
|
||||
fn index_pdu<'a>(&self, shortroomid: u64, pdu_id: &[u8], message_body: String) -> Result<()>;
|
||||
|
||||
fn search_pdus<'a>(
|
||||
&'a self,
|
||||
|
|
|
@ -4,11 +4,16 @@ pub use data::Data;
|
|||
use crate::Result;
|
||||
use ruma::RoomId;
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn index_pdu<'a>(&self, shortroomid: u64, pdu_id: &[u8], message_body: String) -> Result<()> {
|
||||
self.db.index_pdu(shortroomid, pdu_id, message_body)
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn search_pdus<'a>(
|
||||
&'a self,
|
||||
|
|
|
@ -6,11 +6,11 @@ use ruma::{EventId, events::StateEventType, RoomId};
|
|||
|
||||
use crate::{Result, Error, utils, services};
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
pub fn get_or_create_shorteventid(
|
||||
&self,
|
||||
event_id: &EventId,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::sync::Arc;
|
||||
use std::{sync::MutexGuard, collections::HashSet};
|
||||
use std::fmt::Debug;
|
||||
use crate::Result;
|
||||
use ruma::{EventId, RoomId};
|
||||
|
||||
|
@ -22,7 +21,7 @@ pub trait Data {
|
|||
/// Replace the forward extremities of the room.
|
||||
fn set_forward_extremities<'a>(&self,
|
||||
room_id: &RoomId,
|
||||
event_ids: impl IntoIterator<Item = &'a EventId> + Debug,
|
||||
event_ids: &dyn Iterator<Item = &'a EventId>,
|
||||
_mutex_lock: &MutexGuard<'_, ()>, // Take mutex guard to make sure users get the room state mutex
|
||||
) -> Result<()>;
|
||||
}
|
||||
|
|
|
@ -10,11 +10,11 @@ use crate::{Result, services, PduEvent, Error, utils::calculate_hash};
|
|||
|
||||
use super::state_compressor::CompressedStateEvent;
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
/// Set the room to the given statehash and update caches.
|
||||
pub fn force_state(
|
||||
&self,
|
||||
|
@ -23,6 +23,15 @@ impl<D: Data> Service<D> {
|
|||
statediffnew: HashSet<CompressedStateEvent>,
|
||||
statediffremoved: HashSet<CompressedStateEvent>,
|
||||
) -> Result<()> {
|
||||
let mutex_state = Arc::clone(
|
||||
services().globals
|
||||
.roomid_mutex_state
|
||||
.write()
|
||||
.unwrap()
|
||||
.entry(body.room_id.to_owned())
|
||||
.or_default(),
|
||||
);
|
||||
let state_lock = mutex_state.lock().await;
|
||||
|
||||
for event_id in statediffnew.into_iter().filter_map(|new| {
|
||||
services().rooms.state_compressor.parse_compressed_state_event(new)
|
||||
|
@ -70,7 +79,9 @@ impl<D: Data> Service<D> {
|
|||
|
||||
services().room.state_cache.update_joined_count(room_id)?;
|
||||
|
||||
self.db.set_room_state(room_id, shortstatehash);
|
||||
self.db.set_room_state(room_id, shortstatehash, &state_lock);
|
||||
|
||||
drop(state_lock);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -6,11 +6,11 @@ use ruma::{events::StateEventType, RoomId, EventId};
|
|||
|
||||
use crate::{Result, PduEvent};
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
/// Builds a StateMap by iterating over all keys that start
|
||||
/// with state_hash, this gives the full state for the given state_hash.
|
||||
#[tracing::instrument(skip(self))]
|
||||
|
|
|
@ -7,11 +7,11 @@ use ruma::{RoomId, UserId, events::{room::{member::MembershipState, create::Room
|
|||
|
||||
use crate::{Result, services, utils, Error};
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
/// Update current membership data.
|
||||
#[tracing::instrument(skip(self, last_state))]
|
||||
pub fn update_membership(
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
use super::CompressedStateEvent;
|
||||
use crate::Result;
|
||||
|
||||
pub struct StateDiff {
|
||||
parent: Option<u64>,
|
||||
added: Vec<CompressedStateEvent>,
|
||||
removed: Vec<CompressedStateEvent>,
|
||||
pub parent: Option<u64>,
|
||||
pub added: HashSet<CompressedStateEvent>,
|
||||
pub removed: HashSet<CompressedStateEvent>,
|
||||
}
|
||||
|
||||
pub trait Data {
|
||||
|
|
|
@ -8,13 +8,13 @@ use crate::{Result, utils, services};
|
|||
|
||||
use self::data::StateDiff;
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
pub type CompressedStateEvent = [u8; 2 * size_of::<u64>()];
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
/// Returns a stack with info on shortstatehash, full state, added diff and removed diff for the selected shortstatehash and each parent layer.
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn load_shortstatehash_info(
|
||||
|
|
|
@ -20,11 +20,11 @@ use crate::{services, Result, service::pdu::{PduBuilder, EventHash}, Error, PduE
|
|||
|
||||
use super::state_compressor::CompressedStateEvent;
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
/*
|
||||
/// Checks if a room exists.
|
||||
#[tracing::instrument(skip(self))]
|
||||
|
|
|
@ -4,11 +4,11 @@ use ruma::{RoomId, UserId};
|
|||
|
||||
use crate::Result;
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
pub fn reset_notification_counts(&self, user_id: &UserId, room_id: &RoomId) -> Result<()> {
|
||||
self.db.reset_notification_counts(user_id, room_id)
|
||||
}
|
||||
|
|
|
@ -4,11 +4,11 @@ pub use data::Data;
|
|||
use ruma::{UserId, DeviceId, TransactionId};
|
||||
use crate::Result;
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
pub fn add_txnid(
|
||||
&self,
|
||||
user_id: &UserId,
|
||||
|
|
|
@ -6,11 +6,11 @@ use tracing::error;
|
|||
|
||||
use crate::{Result, utils, Error, services, api::client_server::SESSION_ID_LENGTH};
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
/// Creates a new Uiaa session. Make sure the session token is unique.
|
||||
pub fn create(
|
||||
&self,
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::collections::BTreeMap;
|
|||
use crate::Result;
|
||||
use ruma::{UserId, DeviceId, DeviceKeyAlgorithm, DeviceKeyId, serde::Raw, encryption::{OneTimeKey, DeviceKeys, CrossSigningKey}, UInt, events::AnyToDeviceEvent, api::client::{device::Device, filter::IncomingFilterDefinition}, MxcUri};
|
||||
|
||||
pub trait Data {
|
||||
pub trait Data: Send + Sync {
|
||||
/// Check if a user has an account on this homeserver.
|
||||
fn exists(&self, user_id: &UserId) -> Result<bool>;
|
||||
|
||||
|
@ -138,16 +138,16 @@ pub trait Data {
|
|||
device_id: &DeviceId,
|
||||
) -> Result<Option<Raw<DeviceKeys>>>;
|
||||
|
||||
fn get_master_key<F: Fn(&UserId) -> bool>(
|
||||
fn get_master_key(
|
||||
&self,
|
||||
user_id: &UserId,
|
||||
allowed_signatures: F,
|
||||
allowed_signatures: &dyn Fn(&UserId) -> bool,
|
||||
) -> Result<Option<Raw<CrossSigningKey>>>;
|
||||
|
||||
fn get_self_signing_key<F: Fn(&UserId) -> bool>(
|
||||
fn get_self_signing_key(
|
||||
&self,
|
||||
user_id: &UserId,
|
||||
allowed_signatures: F,
|
||||
allowed_signatures: &dyn Fn(&UserId) -> bool,
|
||||
) -> Result<Option<Raw<CrossSigningKey>>>;
|
||||
|
||||
fn get_user_signing_key(&self, user_id: &UserId) -> Result<Option<Raw<CrossSigningKey>>>;
|
||||
|
|
|
@ -6,11 +6,11 @@ use ruma::{UserId, MxcUri, DeviceId, DeviceKeyId, serde::Raw, encryption::{OneTi
|
|||
|
||||
use crate::{Result, Error, services};
|
||||
|
||||
pub struct Service<D: Data> {
|
||||
db: D,
|
||||
pub struct Service {
|
||||
db: Box<dyn Data>,
|
||||
}
|
||||
|
||||
impl<D: Data> Service<D> {
|
||||
impl Service {
|
||||
/// Check if a user has an account on this homeserver.
|
||||
pub fn exists(&self, user_id: &UserId) -> Result<bool> {
|
||||
self.db.exists(user_id)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue