Merge branch 'improvements' into 'master'
Update ruma See merge request famedly/conduit!127
This commit is contained in:
		
						commit
						7d14a46607
					
				
					 27 changed files with 394 additions and 271 deletions
				
			
		
							
								
								
									
										41
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										41
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							|  | @ -2015,7 +2015,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "ruma" | ||||
| version = "0.2.0" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| dependencies = [ | ||||
|  "assign", | ||||
|  "js_int", | ||||
|  | @ -2036,7 +2036,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "ruma-api" | ||||
| version = "0.17.1" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| dependencies = [ | ||||
|  "bytes", | ||||
|  "http", | ||||
|  | @ -2052,7 +2052,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "ruma-api-macros" | ||||
| version = "0.17.1" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| dependencies = [ | ||||
|  "proc-macro-crate", | ||||
|  "proc-macro2", | ||||
|  | @ -2063,7 +2063,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "ruma-appservice-api" | ||||
| version = "0.3.0" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| dependencies = [ | ||||
|  "ruma-api", | ||||
|  "ruma-common", | ||||
|  | @ -2077,7 +2077,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "ruma-client-api" | ||||
| version = "0.11.0" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| dependencies = [ | ||||
|  "assign", | ||||
|  "bytes", | ||||
|  | @ -2097,7 +2097,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "ruma-common" | ||||
| version = "0.5.4" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| dependencies = [ | ||||
|  "indexmap", | ||||
|  "js_int", | ||||
|  | @ -2111,8 +2111,8 @@ dependencies = [ | |||
| 
 | ||||
| [[package]] | ||||
| name = "ruma-events" | ||||
| version = "0.23.1" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| version = "0.23.2" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| dependencies = [ | ||||
|  "indoc", | ||||
|  "js_int", | ||||
|  | @ -2122,12 +2122,13 @@ dependencies = [ | |||
|  "ruma-serde", | ||||
|  "serde", | ||||
|  "serde_json", | ||||
|  "thiserror", | ||||
| ] | ||||
| 
 | ||||
| [[package]] | ||||
| name = "ruma-events-macros" | ||||
| version = "0.23.1" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| version = "0.23.2" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| dependencies = [ | ||||
|  "proc-macro-crate", | ||||
|  "proc-macro2", | ||||
|  | @ -2138,7 +2139,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "ruma-federation-api" | ||||
| version = "0.2.0" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| dependencies = [ | ||||
|  "js_int", | ||||
|  "ruma-api", | ||||
|  | @ -2153,7 +2154,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "ruma-identifiers" | ||||
| version = "0.19.4" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| dependencies = [ | ||||
|  "paste", | ||||
|  "rand 0.8.4", | ||||
|  | @ -2167,7 +2168,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "ruma-identifiers-macros" | ||||
| version = "0.19.4" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| dependencies = [ | ||||
|  "quote", | ||||
|  "ruma-identifiers-validation", | ||||
|  | @ -2177,12 +2178,12 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "ruma-identifiers-validation" | ||||
| version = "0.4.0" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "ruma-identity-service-api" | ||||
| version = "0.2.0" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| dependencies = [ | ||||
|  "js_int", | ||||
|  "ruma-api", | ||||
|  | @ -2195,7 +2196,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "ruma-push-gateway-api" | ||||
| version = "0.2.0" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| dependencies = [ | ||||
|  "js_int", | ||||
|  "ruma-api", | ||||
|  | @ -2210,7 +2211,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "ruma-serde" | ||||
| version = "0.4.1" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| dependencies = [ | ||||
|  "bytes", | ||||
|  "form_urlencoded", | ||||
|  | @ -2224,7 +2225,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "ruma-serde-macros" | ||||
| version = "0.4.1" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| dependencies = [ | ||||
|  "proc-macro-crate", | ||||
|  "proc-macro2", | ||||
|  | @ -2235,7 +2236,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "ruma-signatures" | ||||
| version = "0.8.0" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| dependencies = [ | ||||
|  "base64 0.13.0", | ||||
|  "ed25519-dalek", | ||||
|  | @ -2252,7 +2253,7 @@ dependencies = [ | |||
| [[package]] | ||||
| name = "ruma-state-res" | ||||
| version = "0.2.0" | ||||
| source = "git+https://github.com/ruma/ruma?rev=174555857ef90d49e4b9a672be9e2fe0acdc2687#174555857ef90d49e4b9a672be9e2fe0acdc2687" | ||||
| source = "git+https://github.com/ruma/ruma?rev=eb19b0e08a901b87d11b3be0890ec788cc760492#eb19b0e08a901b87d11b3be0890ec788cc760492" | ||||
| dependencies = [ | ||||
|  "itertools 0.10.1", | ||||
|  "js_int", | ||||
|  |  | |||
|  | @ -18,7 +18,8 @@ edition = "2018" | |||
| rocket = { version = "0.5.0-rc.1", features = ["tls"] } # Used to handle requests | ||||
| 
 | ||||
| # Used for matrix spec type definitions and helpers | ||||
| ruma = { git = "https://github.com/ruma/ruma", rev = "174555857ef90d49e4b9a672be9e2fe0acdc2687", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] } | ||||
| ruma = { git = "https://github.com/ruma/ruma", rev = "eb19b0e08a901b87d11b3be0890ec788cc760492", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] } | ||||
| #ruma = { git = "https://github.com/timokoesters/ruma", rev = "74cf83c4ca937fa5e2709fb71e9d11848e72e487", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] } | ||||
| #ruma = { path = "../ruma/crates/ruma", features = ["compat", "rand", "appservice-api-c", "client-api", "federation-api", "push-gateway-api-c", "state-res", "unstable-pre-spec", "unstable-exhaustive-types"] } | ||||
| 
 | ||||
| # Used for long polling and federation sender, should be the same as rocket::tokio | ||||
|  |  | |||
|  | @ -1,4 +1,8 @@ | |||
| use std::{collections::BTreeMap, convert::TryInto, sync::Arc}; | ||||
| use std::{ | ||||
|     collections::BTreeMap, | ||||
|     convert::{TryFrom, TryInto}, | ||||
|     sync::Arc, | ||||
| }; | ||||
| 
 | ||||
| use super::{DEVICE_ID_LENGTH, SESSION_ID_LENGTH, TOKEN_LENGTH}; | ||||
| use crate::{database::DatabaseGuard, pdu::PduBuilder, utils, ConduitResult, Error, Ruma}; | ||||
|  | @ -21,6 +25,7 @@ use ruma::{ | |||
|         }, | ||||
|         EventType, | ||||
|     }, | ||||
|     identifiers::RoomName, | ||||
|     push, RoomAliasId, RoomId, RoomVersionId, UserId, | ||||
| }; | ||||
| 
 | ||||
|  | @ -278,6 +283,7 @@ pub async fn register_route( | |||
|                     avatar_url: None, | ||||
|                     is_direct: None, | ||||
|                     third_party_invite: None, | ||||
|                     blurhash: None, | ||||
|                 }) | ||||
|                 .expect("event is valid, we just created it"), | ||||
|                 unsigned: None, | ||||
|  | @ -372,15 +378,14 @@ pub async fn register_route( | |||
|         )?; | ||||
| 
 | ||||
|         // 6. Events implied by name and topic
 | ||||
|         let room_name = | ||||
|             Box::<RoomName>::try_from(format!("{} Admin Room", db.globals.server_name())) | ||||
|                 .expect("Room name is valid"); | ||||
|         db.rooms.build_and_append_pdu( | ||||
|             PduBuilder { | ||||
|                 event_type: EventType::RoomName, | ||||
|                 content: serde_json::to_value( | ||||
|                     name::NameEventContent::new("Admin Room".to_owned()).map_err(|_| { | ||||
|                         Error::BadRequest(ErrorKind::InvalidParam, "Name is invalid.") | ||||
|                     })?, | ||||
|                 ) | ||||
|                 .expect("event is valid, we just created it"), | ||||
|                 content: serde_json::to_value(name::NameEventContent::new(Some(room_name))) | ||||
|                     .expect("event is valid, we just created it"), | ||||
|                 unsigned: None, | ||||
|                 state_key: Some("".to_owned()), | ||||
|                 redacts: None, | ||||
|  | @ -443,6 +448,7 @@ pub async fn register_route( | |||
|                     avatar_url: None, | ||||
|                     is_direct: None, | ||||
|                     third_party_invite: None, | ||||
|                     blurhash: None, | ||||
|                 }) | ||||
|                 .expect("event is valid, we just created it"), | ||||
|                 unsigned: None, | ||||
|  | @ -463,6 +469,7 @@ pub async fn register_route( | |||
|                     avatar_url: None, | ||||
|                     is_direct: None, | ||||
|                     third_party_invite: None, | ||||
|                     blurhash: None, | ||||
|                 }) | ||||
|                 .expect("event is valid, we just created it"), | ||||
|                 unsigned: None, | ||||
|  | @ -575,7 +582,7 @@ pub async fn change_password_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(change_password::Response.into()) | ||||
|     Ok(change_password::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| /// # `GET _matrix/client/r0/account/whoami`
 | ||||
|  | @ -661,6 +668,7 @@ pub async fn deactivate_route( | |||
|             avatar_url: None, | ||||
|             is_direct: None, | ||||
|             third_party_invite: None, | ||||
|             blurhash: None, | ||||
|         }; | ||||
| 
 | ||||
|         let mutex = Arc::clone( | ||||
|  |  | |||
|  | @ -46,7 +46,7 @@ pub async fn update_backup_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(update_backup::Response.into()) | ||||
|     Ok(update_backup::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  | @ -119,7 +119,7 @@ pub async fn delete_backup_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(delete_backup::Response.into()) | ||||
|     Ok(delete_backup::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| /// Add the received backup keys to the database.
 | ||||
|  |  | |||
|  | @ -45,7 +45,7 @@ pub async fn set_global_account_data_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(set_global_account_data::Response.into()) | ||||
|     Ok(set_global_account_data::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  | @ -80,7 +80,7 @@ pub async fn set_room_account_data_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(set_room_account_data::Response.into()) | ||||
|     Ok(set_room_account_data::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  |  | |||
|  | @ -73,7 +73,7 @@ pub async fn update_device_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(update_device::Response.into()) | ||||
|     Ok(update_device::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  | @ -125,7 +125,7 @@ pub async fn delete_device_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(delete_device::Response.into()) | ||||
|     Ok(delete_device::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  | @ -179,5 +179,5 @@ pub async fn delete_devices_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(delete_devices::Response.into()) | ||||
|     Ok(delete_devices::Response {}.into()) | ||||
| } | ||||
|  |  | |||
|  | @ -87,22 +87,22 @@ pub async fn set_room_visibility_route( | |||
|     let sender_user = body.sender_user.as_ref().expect("user is authenticated"); | ||||
| 
 | ||||
|     match &body.visibility { | ||||
|         room::Visibility::_Custom(_s) => { | ||||
|             return Err(Error::BadRequest( | ||||
|                 ErrorKind::InvalidParam, | ||||
|                 "Room visibility type is not supported.", | ||||
|             )); | ||||
|         } | ||||
|         room::Visibility::Public => { | ||||
|             db.rooms.set_public(&body.room_id, true)?; | ||||
|             info!("{} made {} public", sender_user, body.room_id); | ||||
|         } | ||||
|         room::Visibility::Private => db.rooms.set_public(&body.room_id, false)?, | ||||
|         _ => { | ||||
|             return Err(Error::BadRequest( | ||||
|                 ErrorKind::InvalidParam, | ||||
|                 "Room visibility type is not supported.", | ||||
|             )); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(set_room_visibility::Response.into()) | ||||
|     Ok(set_room_visibility::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  | @ -231,8 +231,8 @@ pub async fn get_public_rooms_filtered_helper( | |||
|                             .map_err(|_| { | ||||
|                                 Error::bad_database("Invalid room name event in database.") | ||||
|                             })? | ||||
|                             .name() | ||||
|                             .map(|n| n.to_owned())) | ||||
|                             .name | ||||
|                             .map(|n| n.to_owned().into())) | ||||
|                         })?, | ||||
|                     num_joined_members: (db.rooms.room_members(&room_id).count() as u32).into(), | ||||
|                     topic: db | ||||
|  | @ -316,7 +316,7 @@ pub async fn get_public_rooms_filtered_helper( | |||
|                     .map(|q| q.to_lowercase()) | ||||
|                 { | ||||
|                     if let Some(name) = &chunk.name { | ||||
|                         if name.to_lowercase().contains(&query) { | ||||
|                         if name.as_str().to_lowercase().contains(&query) { | ||||
|                             return true; | ||||
|                         } | ||||
|                     } | ||||
|  |  | |||
|  | @ -163,7 +163,7 @@ pub async fn upload_signing_keys_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(upload_signing_keys::Response.into()) | ||||
|     Ok(upload_signing_keys::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  | @ -224,7 +224,7 @@ pub async fn upload_signatures_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(upload_signatures::Response.into()) | ||||
|     Ok(upload_signatures::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  |  | |||
|  | @ -29,7 +29,7 @@ use ruma::{ | |||
|     uint, EventId, RoomId, RoomVersionId, ServerName, UserId, | ||||
| }; | ||||
| use std::{ | ||||
|     collections::{btree_map::Entry, BTreeMap, HashSet}, | ||||
|     collections::{hash_map::Entry, BTreeMap, HashMap, HashSet}, | ||||
|     convert::{TryFrom, TryInto}, | ||||
|     sync::{Arc, RwLock}, | ||||
|     time::{Duration, Instant}, | ||||
|  | @ -165,7 +165,7 @@ pub async fn invite_user_route( | |||
|     if let invite_user::IncomingInvitationRecipient::UserId { user_id } = &body.recipient { | ||||
|         invite_helper(sender_user, user_id, &body.room_id, &db, false).await?; | ||||
|         db.flush().await?; | ||||
|         Ok(invite_user::Response.into()) | ||||
|         Ok(invite_user::Response {}.into()) | ||||
|     } else { | ||||
|         Err(Error::BadRequest(ErrorKind::NotFound, "User not found.")) | ||||
|     } | ||||
|  | @ -261,6 +261,7 @@ pub async fn ban_user_route( | |||
|                 avatar_url: db.users.avatar_url(&body.user_id)?, | ||||
|                 is_direct: None, | ||||
|                 third_party_invite: None, | ||||
|                 blurhash: db.users.blurhash(&body.user_id)?, | ||||
|             }), | ||||
|             |event| { | ||||
|                 let mut event = serde_json::from_value::<Raw<member::MemberEventContent>>( | ||||
|  | @ -556,6 +557,7 @@ async fn join_room_by_id_helper( | |||
|                 avatar_url: db.users.avatar_url(&sender_user)?, | ||||
|                 is_direct: None, | ||||
|                 third_party_invite: None, | ||||
|                 blurhash: db.users.blurhash(&sender_user)?, | ||||
|             }) | ||||
|             .expect("event is valid, we just created it"), | ||||
|         ); | ||||
|  | @ -605,7 +607,7 @@ async fn join_room_by_id_helper( | |||
|         let pdu = PduEvent::from_id_val(&event_id, join_event.clone()) | ||||
|             .map_err(|_| Error::BadServerResponse("Invalid join event PDU."))?; | ||||
| 
 | ||||
|         let mut state = BTreeMap::new(); | ||||
|         let mut state = HashMap::new(); | ||||
|         let pub_key_map = RwLock::new(BTreeMap::new()); | ||||
| 
 | ||||
|         for result in futures::future::join_all( | ||||
|  | @ -685,6 +687,7 @@ async fn join_room_by_id_helper( | |||
|             avatar_url: db.users.avatar_url(&sender_user)?, | ||||
|             is_direct: None, | ||||
|             third_party_invite: None, | ||||
|             blurhash: db.users.blurhash(&sender_user)?, | ||||
|         }; | ||||
| 
 | ||||
|         db.rooms.build_and_append_pdu( | ||||
|  | @ -833,6 +836,7 @@ pub async fn invite_helper<'a>( | |||
|             is_direct: Some(is_direct), | ||||
|             membership: MembershipState::Invite, | ||||
|             third_party_invite: None, | ||||
|             blurhash: db.users.blurhash(&sender_user)?, | ||||
|         }) | ||||
|         .expect("member event is valid value"); | ||||
| 
 | ||||
|  | @ -1008,6 +1012,7 @@ pub async fn invite_helper<'a>( | |||
|                 avatar_url: db.users.avatar_url(&user_id)?, | ||||
|                 is_direct: Some(is_direct), | ||||
|                 third_party_invite: None, | ||||
|                 blurhash: db.users.blurhash(&sender_user)?, | ||||
|             }) | ||||
|             .expect("event is valid, we just created it"), | ||||
|             unsigned: None, | ||||
|  |  | |||
|  | @ -75,5 +75,5 @@ pub const SESSION_ID_LENGTH: usize = 256; | |||
| #[options("/<_..>")] | ||||
| #[tracing::instrument] | ||||
| pub async fn options_route() -> ConduitResult<send_event_to_device::Response> { | ||||
|     Ok(send_event_to_device::Response.into()) | ||||
|     Ok(send_event_to_device::Response {}.into()) | ||||
| } | ||||
|  |  | |||
|  | @ -43,7 +43,7 @@ pub async fn set_presence_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(set_presence::Response.into()) | ||||
|     Ok(set_presence::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  |  | |||
|  | @ -108,7 +108,7 @@ pub async fn set_displayname_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(set_display_name::Response.into()) | ||||
|     Ok(set_display_name::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  | @ -140,6 +140,8 @@ pub async fn set_avatar_url_route( | |||
|     db.users | ||||
|         .set_avatar_url(&sender_user, body.avatar_url.clone())?; | ||||
| 
 | ||||
|     db.users.set_blurhash(&sender_user, body.blurhash.clone())?; | ||||
| 
 | ||||
|     // Send a new membership event and presence update into all joined rooms
 | ||||
|     for (pdu_builder, room_id) in db | ||||
|         .rooms | ||||
|  | @ -220,7 +222,7 @@ pub async fn set_avatar_url_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(set_avatar_url::Response.into()) | ||||
|     Ok(set_avatar_url::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  | @ -234,6 +236,7 @@ pub async fn get_avatar_url_route( | |||
| ) -> ConduitResult<get_avatar_url::Response> { | ||||
|     Ok(get_avatar_url::Response { | ||||
|         avatar_url: db.users.avatar_url(&body.user_id)?, | ||||
|         blurhash: db.users.blurhash(&body.user_id)?, | ||||
|     } | ||||
|     .into()) | ||||
| } | ||||
|  | @ -257,6 +260,7 @@ pub async fn get_profile_route( | |||
| 
 | ||||
|     Ok(get_profile::Response { | ||||
|         avatar_url: db.users.avatar_url(&body.user_id)?, | ||||
|         blurhash: db.users.blurhash(&body.user_id)?, | ||||
|         displayname: db.users.displayname(&body.user_id)?, | ||||
|     } | ||||
|     .into()) | ||||
|  |  | |||
|  | @ -81,7 +81,7 @@ pub async fn get_pushrule_route( | |||
|             .content | ||||
|             .get(body.rule_id.as_str()) | ||||
|             .map(|rule| rule.clone().into()), | ||||
|         RuleKind::_Custom(_) => None, | ||||
|         _ => None, | ||||
|     }; | ||||
| 
 | ||||
|     if let Some(rule) = rule { | ||||
|  | @ -181,7 +181,7 @@ pub async fn set_pushrule_route( | |||
|                 .into(), | ||||
|             ); | ||||
|         } | ||||
|         RuleKind::_Custom(_) => {} | ||||
|         _ => {} | ||||
|     } | ||||
| 
 | ||||
|     db.account_data.update( | ||||
|  | @ -194,7 +194,7 @@ pub async fn set_pushrule_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(set_pushrule::Response.into()) | ||||
|     Ok(set_pushrule::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  | @ -245,7 +245,7 @@ pub async fn get_pushrule_actions_route( | |||
|             .content | ||||
|             .get(body.rule_id.as_str()) | ||||
|             .map(|rule| rule.actions.clone()), | ||||
|         RuleKind::_Custom(_) => None, | ||||
|         _ => None, | ||||
|     }; | ||||
| 
 | ||||
|     db.flush().await?; | ||||
|  | @ -314,7 +314,7 @@ pub async fn set_pushrule_actions_route( | |||
|                 global.content.replace(rule); | ||||
|             } | ||||
|         } | ||||
|         RuleKind::_Custom(_) => {} | ||||
|         _ => {} | ||||
|     }; | ||||
| 
 | ||||
|     db.account_data.update( | ||||
|  | @ -327,7 +327,7 @@ pub async fn set_pushrule_actions_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(set_pushrule_actions::Response.into()) | ||||
|     Ok(set_pushrule_actions::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  | @ -383,7 +383,7 @@ pub async fn get_pushrule_enabled_route( | |||
|             .iter() | ||||
|             .find(|rule| rule.rule_id == body.rule_id) | ||||
|             .map_or(false, |rule| rule.enabled), | ||||
|         RuleKind::_Custom(_) => false, | ||||
|         _ => false, | ||||
|     }; | ||||
| 
 | ||||
|     db.flush().await?; | ||||
|  | @ -454,7 +454,7 @@ pub async fn set_pushrule_enabled_route( | |||
|                 global.content.insert(rule); | ||||
|             } | ||||
|         } | ||||
|         RuleKind::_Custom(_) => {} | ||||
|         _ => {} | ||||
|     } | ||||
| 
 | ||||
|     db.account_data.update( | ||||
|  | @ -467,7 +467,7 @@ pub async fn set_pushrule_enabled_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(set_pushrule_enabled::Response.into()) | ||||
|     Ok(set_pushrule_enabled::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  | @ -523,7 +523,7 @@ pub async fn delete_pushrule_route( | |||
|                 global.content.remove(&rule); | ||||
|             } | ||||
|         } | ||||
|         RuleKind::_Custom(_) => {} | ||||
|         _ => {} | ||||
|     } | ||||
| 
 | ||||
|     db.account_data.update( | ||||
|  | @ -536,7 +536,7 @@ pub async fn delete_pushrule_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(delete_pushrule::Response.into()) | ||||
|     Ok(delete_pushrule::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  |  | |||
|  | @ -77,7 +77,7 @@ pub async fn set_read_marker_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(set_read_marker::Response.into()) | ||||
|     Ok(set_read_marker::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  | @ -130,5 +130,5 @@ pub async fn create_receipt_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(create_receipt::Response.into()) | ||||
|     Ok(create_receipt::Response {}.into()) | ||||
| } | ||||
|  |  | |||
|  | @ -92,6 +92,7 @@ pub async fn create_room_route( | |||
|                 avatar_url: db.users.avatar_url(&sender_user)?, | ||||
|                 is_direct: Some(body.is_direct), | ||||
|                 third_party_invite: None, | ||||
|                 blurhash: db.users.blurhash(&sender_user)?, | ||||
|             }) | ||||
|             .expect("event is valid, we just created it"), | ||||
|             unsigned: None, | ||||
|  | @ -113,7 +114,7 @@ pub async fn create_room_route( | |||
|         .unwrap_or_else(|| match &body.visibility { | ||||
|             room::Visibility::Private => create_room::RoomPreset::PrivateChat, | ||||
|             room::Visibility::Public => create_room::RoomPreset::PublicChat, | ||||
|             room::Visibility::_Custom(_) => create_room::RoomPreset::PrivateChat, // Room visibility should not be custom
 | ||||
|             _ => create_room::RoomPreset::PrivateChat, // Room visibility should not be custom
 | ||||
|         }); | ||||
| 
 | ||||
|     let mut users = BTreeMap::new(); | ||||
|  | @ -251,12 +252,8 @@ pub async fn create_room_route( | |||
|         db.rooms.build_and_append_pdu( | ||||
|             PduBuilder { | ||||
|                 event_type: EventType::RoomName, | ||||
|                 content: serde_json::to_value( | ||||
|                     name::NameEventContent::new(name.clone()).map_err(|_| { | ||||
|                         Error::BadRequest(ErrorKind::InvalidParam, "Name is invalid.") | ||||
|                     })?, | ||||
|                 ) | ||||
|                 .expect("event is valid, we just created it"), | ||||
|                 content: serde_json::to_value(name::NameEventContent::new(Some(name.clone()))) | ||||
|                     .expect("event is valid, we just created it"), | ||||
|                 unsigned: None, | ||||
|                 state_key: Some("".to_owned()), | ||||
|                 redacts: None, | ||||
|  | @ -440,6 +437,7 @@ pub async fn upgrade_room_route( | |||
|                 avatar_url: db.users.avatar_url(&sender_user)?, | ||||
|                 is_direct: None, | ||||
|                 third_party_invite: None, | ||||
|                 blurhash: db.users.blurhash(&sender_user)?, | ||||
|             }) | ||||
|             .expect("event is valid, we just created it"), | ||||
|             unsigned: None, | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| use crate::{database::DatabaseGuard, ConduitResult, Database, Error, Result, Ruma, RumaResponse}; | ||||
| use log::error; | ||||
| use log::{error, warn}; | ||||
| use ruma::{ | ||||
|     api::client::r0::{sync::sync_events, uiaa::UiaaResponse}, | ||||
|     events::{room::member::MembershipState, AnySyncEphemeralRoomEvent, EventType}, | ||||
|  | @ -7,7 +7,7 @@ use ruma::{ | |||
|     DeviceId, RoomId, UserId, | ||||
| }; | ||||
| use std::{ | ||||
|     collections::{btree_map::Entry, hash_map, BTreeMap, HashMap, HashSet}, | ||||
|     collections::{hash_map::Entry, BTreeMap, HashMap, HashSet}, | ||||
|     convert::{TryFrom, TryInto}, | ||||
|     sync::Arc, | ||||
|     time::Duration, | ||||
|  | @ -262,8 +262,12 @@ async fn sync_helper( | |||
|                 db.rooms | ||||
|                     .pdu_shortstatehash(&pdu.1.event_id) | ||||
|                     .transpose() | ||||
|                     .expect("all pdus have state") | ||||
|                     .ok_or_else(|| { | ||||
|                         warn!("PDU without state: {}", pdu.1.event_id); | ||||
|                         Error::bad_database("Found PDU without state") | ||||
|                     }) | ||||
|             }) | ||||
|             .transpose()? | ||||
|             .transpose()?; | ||||
| 
 | ||||
|         // Calculates joined_member_count, invited_member_count and heroes
 | ||||
|  | @ -622,10 +626,10 @@ async fn sync_helper( | |||
|                 .presence_since(&room_id, since, &db.rooms, &db.globals)? | ||||
|         { | ||||
|             match presence_updates.entry(user_id) { | ||||
|                 hash_map::Entry::Vacant(v) => { | ||||
|                 Entry::Vacant(v) => { | ||||
|                     v.insert(presence); | ||||
|                 } | ||||
|                 hash_map::Entry::Occupied(mut o) => { | ||||
|                 Entry::Occupied(mut o) => { | ||||
|                     let p = o.get_mut(); | ||||
| 
 | ||||
|                     // Update existing presence event with more info
 | ||||
|  | @ -753,6 +757,7 @@ async fn sync_helper( | |||
|             leave: left_rooms, | ||||
|             join: joined_rooms, | ||||
|             invite: invited_rooms, | ||||
|             knock: BTreeMap::new(), // TODO
 | ||||
|         }, | ||||
|         presence: sync_events::Presence { | ||||
|             events: presence_updates | ||||
|  |  | |||
|  | @ -42,7 +42,7 @@ pub async fn update_tag_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(create_tag::Response.into()) | ||||
|     Ok(create_tag::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  | @ -76,7 +76,7 @@ pub async fn delete_tag_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(delete_tag::Response.into()) | ||||
|     Ok(delete_tag::Response {}.into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  |  | |||
|  | @ -69,5 +69,5 @@ pub async fn send_event_to_device_route( | |||
| 
 | ||||
|     db.flush().await?; | ||||
| 
 | ||||
|     Ok(send_event_to_device::Response.into()) | ||||
|     Ok(send_event_to_device::Response {}.into()) | ||||
| } | ||||
|  |  | |||
|  | @ -29,5 +29,5 @@ pub fn create_typing_event_route( | |||
|             .typing_remove(&sender_user, &body.room_id, &db.globals)?; | ||||
|     } | ||||
| 
 | ||||
|     Ok(create_typing_event::Response.into()) | ||||
|     Ok(create_typing_event::Response {}.into()) | ||||
| } | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ use std::{ | |||
|     io::Write, | ||||
|     ops::Deref, | ||||
|     path::Path, | ||||
|     sync::{Arc, RwLock}, | ||||
|     sync::{Arc, Mutex, RwLock}, | ||||
| }; | ||||
| use tokio::sync::{OwnedRwLockReadGuard, RwLock as TokioRwLock, Semaphore}; | ||||
| 
 | ||||
|  | @ -229,6 +229,7 @@ impl Database { | |||
|                 userid_password: builder.open_tree("userid_password")?, | ||||
|                 userid_displayname: builder.open_tree("userid_displayname")?, | ||||
|                 userid_avatarurl: builder.open_tree("userid_avatarurl")?, | ||||
|                 userid_blurhash: builder.open_tree("userid_blurhash")?, | ||||
|                 userdeviceid_token: builder.open_tree("userdeviceid_token")?, | ||||
|                 userdeviceid_metadata: builder.open_tree("userdeviceid_metadata")?, | ||||
|                 userid_devicelistversion: builder.open_tree("userid_devicelistversion")?, | ||||
|  | @ -291,7 +292,8 @@ impl Database { | |||
| 
 | ||||
|                 eventid_outlierpdu: builder.open_tree("eventid_outlierpdu")?, | ||||
|                 prevevent_parent: builder.open_tree("prevevent_parent")?, | ||||
|                 pdu_cache: RwLock::new(LruCache::new(10_000)), | ||||
|                 pdu_cache: Mutex::new(LruCache::new(100_000)), | ||||
|                 auth_chain_cache: Mutex::new(LruCache::new(100_000)), | ||||
|             }, | ||||
|             account_data: account_data::AccountData { | ||||
|                 roomuserdataid_accountdata: builder.open_tree("roomuserdataid_accountdata")?, | ||||
|  |  | |||
|  | @ -5,14 +5,14 @@ use std::{future::Future, pin::Pin, sync::Arc}; | |||
| 
 | ||||
| use super::{DatabaseEngine, Tree}; | ||||
| 
 | ||||
| use std::{collections::BTreeMap, sync::RwLock}; | ||||
| use std::{collections::HashMap, sync::RwLock}; | ||||
| 
 | ||||
| pub struct Engine(rocksdb::DBWithThreadMode<rocksdb::MultiThreaded>); | ||||
| 
 | ||||
| pub struct RocksDbEngineTree<'a> { | ||||
|     db: Arc<Engine>, | ||||
|     name: &'a str, | ||||
|     watchers: RwLock<BTreeMap<Vec<u8>, Vec<tokio::sync::oneshot::Sender<()>>>>, | ||||
|     watchers: RwLock<HashMap<Vec<u8>, Vec<tokio::sync::oneshot::Sender<()>>>>, | ||||
| } | ||||
| 
 | ||||
| impl DatabaseEngine for Engine { | ||||
|  | @ -58,7 +58,7 @@ impl DatabaseEngine for Engine { | |||
|         Ok(Arc::new(RocksDbEngineTree { | ||||
|             name, | ||||
|             db: Arc::clone(self), | ||||
|             watchers: RwLock::new(BTreeMap::new()), | ||||
|             watchers: RwLock::new(HashMap::new()), | ||||
|         })) | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -7,7 +7,7 @@ use log::debug; | |||
| use parking_lot::{Mutex, MutexGuard, RwLock}; | ||||
| use rusqlite::{params, Connection, DatabaseName::Main, OptionalExtension}; | ||||
| use std::{ | ||||
|     collections::BTreeMap, | ||||
|     collections::HashMap, | ||||
|     future::Future, | ||||
|     ops::Deref, | ||||
|     path::{Path, PathBuf}, | ||||
|  | @ -206,7 +206,7 @@ impl DatabaseEngine for Engine { | |||
|         Ok(Arc::new(SqliteTable { | ||||
|             engine: Arc::clone(self), | ||||
|             name: name.to_owned(), | ||||
|             watchers: RwLock::new(BTreeMap::new()), | ||||
|             watchers: RwLock::new(HashMap::new()), | ||||
|         })) | ||||
|     } | ||||
| 
 | ||||
|  | @ -266,7 +266,7 @@ impl Engine { | |||
| pub struct SqliteTable { | ||||
|     engine: Arc<Engine>, | ||||
|     name: String, | ||||
|     watchers: RwLock<BTreeMap<Vec<u8>, Vec<Sender<()>>>>, | ||||
|     watchers: RwLock<HashMap<Vec<u8>, Vec<Sender<()>>>>, | ||||
| } | ||||
| 
 | ||||
| type TupleOfBytes = (Vec<u8>, Vec<u8>); | ||||
|  |  | |||
|  | @ -41,12 +41,12 @@ pub struct Globals { | |||
|     dns_resolver: TokioAsyncResolver, | ||||
|     jwt_decoding_key: Option<jsonwebtoken::DecodingKey<'static>>, | ||||
|     pub(super) server_signingkeys: Arc<dyn Tree>, | ||||
|     pub bad_event_ratelimiter: Arc<RwLock<BTreeMap<EventId, RateLimitState>>>, | ||||
|     pub bad_signature_ratelimiter: Arc<RwLock<BTreeMap<Vec<String>, RateLimitState>>>, | ||||
|     pub servername_ratelimiter: Arc<RwLock<BTreeMap<Box<ServerName>, Arc<Semaphore>>>>, | ||||
|     pub sync_receivers: RwLock<BTreeMap<(UserId, Box<DeviceId>), SyncHandle>>, | ||||
|     pub roomid_mutex: RwLock<BTreeMap<RoomId, Arc<Mutex<()>>>>, | ||||
|     pub roomid_mutex_federation: RwLock<BTreeMap<RoomId, Arc<Mutex<()>>>>, // this lock will be held longer
 | ||||
|     pub bad_event_ratelimiter: Arc<RwLock<HashMap<EventId, RateLimitState>>>, | ||||
|     pub bad_signature_ratelimiter: Arc<RwLock<HashMap<Vec<String>, RateLimitState>>>, | ||||
|     pub servername_ratelimiter: Arc<RwLock<HashMap<Box<ServerName>, Arc<Semaphore>>>>, | ||||
|     pub sync_receivers: RwLock<HashMap<(UserId, Box<DeviceId>), SyncHandle>>, | ||||
|     pub roomid_mutex: RwLock<HashMap<RoomId, Arc<Mutex<()>>>>, | ||||
|     pub roomid_mutex_federation: RwLock<HashMap<RoomId, Arc<Mutex<()>>>>, // this lock will be held longer
 | ||||
|     pub rotate: RotationHandler, | ||||
| } | ||||
| 
 | ||||
|  | @ -196,12 +196,12 @@ impl Globals { | |||
|             tls_name_override, | ||||
|             server_signingkeys, | ||||
|             jwt_decoding_key, | ||||
|             bad_event_ratelimiter: Arc::new(RwLock::new(BTreeMap::new())), | ||||
|             bad_signature_ratelimiter: Arc::new(RwLock::new(BTreeMap::new())), | ||||
|             servername_ratelimiter: Arc::new(RwLock::new(BTreeMap::new())), | ||||
|             roomid_mutex: RwLock::new(BTreeMap::new()), | ||||
|             roomid_mutex_federation: RwLock::new(BTreeMap::new()), | ||||
|             sync_receivers: RwLock::new(BTreeMap::new()), | ||||
|             bad_event_ratelimiter: Arc::new(RwLock::new(HashMap::new())), | ||||
|             bad_signature_ratelimiter: Arc::new(RwLock::new(HashMap::new())), | ||||
|             servername_ratelimiter: Arc::new(RwLock::new(HashMap::new())), | ||||
|             roomid_mutex: RwLock::new(HashMap::new()), | ||||
|             roomid_mutex_federation: RwLock::new(HashMap::new()), | ||||
|             sync_receivers: RwLock::new(HashMap::new()), | ||||
|             rotate: RotationHandler::new(), | ||||
|         }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ use ruma::{ | |||
|         IncomingResponse, OutgoingRequest, SendAccessToken, | ||||
|     }, | ||||
|     events::{room::power_levels::PowerLevelsEventContent, EventType}, | ||||
|     identifiers::RoomName, | ||||
|     push::{Action, PushConditionRoomCtx, PushFormat, Ruleset, Tweak}, | ||||
|     uint, UInt, UserId, | ||||
| }; | ||||
|  | @ -299,7 +300,9 @@ async fn send_notice( | |||
|             .rooms | ||||
|             .room_state_get(&event.room_id, &EventType::RoomName, "")? | ||||
|             .map(|pdu| match pdu.content.get("name") { | ||||
|                 Some(serde_json::Value::String(s)) => Some(s.to_string()), | ||||
|                 Some(serde_json::Value::String(s)) => { | ||||
|                     Some(Box::<RoomName>::try_from(&**s).expect("room name is valid")) | ||||
|                 } | ||||
|                 _ => None, | ||||
|             }) | ||||
|             .flatten(); | ||||
|  |  | |||
|  | @ -25,7 +25,7 @@ use std::{ | |||
|     collections::{BTreeMap, BTreeSet, HashMap, HashSet}, | ||||
|     convert::{TryFrom, TryInto}, | ||||
|     mem, | ||||
|     sync::{Arc, RwLock}, | ||||
|     sync::{Arc, Mutex}, | ||||
| }; | ||||
| 
 | ||||
| use super::{abstraction::Tree, admin::AdminCommand, pusher}; | ||||
|  | @ -84,7 +84,8 @@ pub struct Rooms { | |||
|     /// RoomId + EventId -> Parent PDU EventId.
 | ||||
|     pub(super) prevevent_parent: Arc<dyn Tree>, | ||||
| 
 | ||||
|     pub(super) pdu_cache: RwLock<LruCache<EventId, Arc<PduEvent>>>, | ||||
|     pub(super) pdu_cache: Mutex<LruCache<EventId, Arc<PduEvent>>>, | ||||
|     pub(super) auth_chain_cache: Mutex<LruCache<EventId, HashSet<EventId>>>, | ||||
| } | ||||
| 
 | ||||
| impl Rooms { | ||||
|  | @ -109,7 +110,7 @@ impl Rooms { | |||
|     pub fn state_full( | ||||
|         &self, | ||||
|         shortstatehash: u64, | ||||
|     ) -> Result<BTreeMap<(EventType, String), Arc<PduEvent>>> { | ||||
|     ) -> Result<HashMap<(EventType, String), Arc<PduEvent>>> { | ||||
|         let state = self | ||||
|             .stateid_shorteventid | ||||
|             .scan_prefix(shortstatehash.to_be_bytes().to_vec()) | ||||
|  | @ -282,7 +283,7 @@ impl Rooms { | |||
|     pub fn force_state( | ||||
|         &self, | ||||
|         room_id: &RoomId, | ||||
|         state: BTreeMap<(EventType, String), EventId>, | ||||
|         state: HashMap<(EventType, String), EventId>, | ||||
|         db: &Database, | ||||
|     ) -> Result<()> { | ||||
|         let state_hash = self.calculate_hash( | ||||
|  | @ -402,11 +403,11 @@ impl Rooms { | |||
|     pub fn room_state_full( | ||||
|         &self, | ||||
|         room_id: &RoomId, | ||||
|     ) -> Result<BTreeMap<(EventType, String), Arc<PduEvent>>> { | ||||
|     ) -> Result<HashMap<(EventType, String), Arc<PduEvent>>> { | ||||
|         if let Some(current_shortstatehash) = self.current_shortstatehash(room_id)? { | ||||
|             self.state_full(current_shortstatehash) | ||||
|         } else { | ||||
|             Ok(BTreeMap::new()) | ||||
|             Ok(HashMap::new()) | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -490,6 +491,27 @@ impl Rooms { | |||
|             .transpose() | ||||
|     } | ||||
| 
 | ||||
|     /// Returns the json of a pdu.
 | ||||
|     pub fn get_non_outlier_pdu_json( | ||||
|         &self, | ||||
|         event_id: &EventId, | ||||
|     ) -> Result<Option<CanonicalJsonObject>> { | ||||
|         self.eventid_pduid | ||||
|             .get(event_id.as_bytes())? | ||||
|             .map_or_else::<Result<_>, _, _>( | ||||
|                 || Ok(None), | ||||
|                 |pduid| { | ||||
|                     Ok(Some(self.pduid_pdu.get(&pduid)?.ok_or_else(|| { | ||||
|                         Error::bad_database("Invalid pduid in eventid_pduid.") | ||||
|                     })?)) | ||||
|                 }, | ||||
|             )? | ||||
|             .map(|pdu| { | ||||
|                 serde_json::from_slice(&pdu).map_err(|_| Error::bad_database("Invalid PDU in db.")) | ||||
|             }) | ||||
|             .transpose() | ||||
|     } | ||||
| 
 | ||||
|     /// Returns the pdu's id.
 | ||||
|     pub fn get_pdu_id(&self, event_id: &EventId) -> Result<Option<Vec<u8>>> { | ||||
|         self.eventid_pduid | ||||
|  | @ -521,7 +543,7 @@ impl Rooms { | |||
|     ///
 | ||||
|     /// Checks the `eventid_outlierpdu` Tree if not found in the timeline.
 | ||||
|     pub fn get_pdu(&self, event_id: &EventId) -> Result<Option<Arc<PduEvent>>> { | ||||
|         if let Some(p) = self.pdu_cache.write().unwrap().get_mut(&event_id) { | ||||
|         if let Some(p) = self.pdu_cache.lock().unwrap().get_mut(&event_id) { | ||||
|             return Ok(Some(Arc::clone(p))); | ||||
|         } | ||||
| 
 | ||||
|  | @ -547,7 +569,7 @@ impl Rooms { | |||
|             .transpose()? | ||||
|         { | ||||
|             self.pdu_cache | ||||
|                 .write() | ||||
|                 .lock() | ||||
|                 .unwrap() | ||||
|                 .insert(event_id.clone(), Arc::clone(&pdu)); | ||||
|             Ok(Some(pdu)) | ||||
|  | @ -631,9 +653,9 @@ impl Rooms { | |||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
|     pub fn is_pdu_referenced(&self, pdu: &PduEvent) -> Result<bool> { | ||||
|         let mut key = pdu.room_id().as_bytes().to_vec(); | ||||
|         key.extend_from_slice(pdu.event_id().as_bytes()); | ||||
|     pub fn is_event_referenced(&self, room_id: &RoomId, event_id: &EventId) -> Result<bool> { | ||||
|         let mut key = room_id.as_bytes().to_vec(); | ||||
|         key.extend_from_slice(event_id.as_bytes()); | ||||
|         Ok(self.prevevent_parent.get(&key)?.is_some()) | ||||
|     } | ||||
| 
 | ||||
|  | @ -903,11 +925,59 @@ impl Rooms { | |||
|                                 "list_appservices" => { | ||||
|                                     db.admin.send(AdminCommand::ListAppservices); | ||||
|                                 } | ||||
|                                 "get_pdu" => { | ||||
|                                     if args.len() == 1 { | ||||
|                                         if let Ok(event_id) = EventId::try_from(args[0]) { | ||||
|                                             let mut outlier = false; | ||||
|                                             let mut pdu_json = | ||||
|                                                 db.rooms.get_non_outlier_pdu_json(&event_id)?; | ||||
|                                             if pdu_json.is_none() { | ||||
|                                                 outlier = true; | ||||
|                                                 pdu_json = db.rooms.get_pdu_json(&event_id)?; | ||||
|                                             } | ||||
|                                             match pdu_json { | ||||
|                                                 Some(json) => { | ||||
|                                                     db.admin.send(AdminCommand::SendMessage( | ||||
|                                                         message::MessageEventContent::text_html( | ||||
|                                                             format!("{}\n```json\n{:#?}\n```", 
 | ||||
|                                                             if outlier { | ||||
|                                                                 "PDU is outlier" | ||||
|                                                             } else { "PDU was accepted"}, json), | ||||
|                                                             format!("<p>{}</p>\n<pre><code class=\"language-json\">{}\n</code></pre>\n", 
 | ||||
|                                                             if outlier { | ||||
|                                                                 "PDU is outlier" | ||||
|                                                             } else { "PDU was accepted"}, serde_json::to_string_pretty(&json).expect("canonical json is valid json")) | ||||
|                                                         ), | ||||
|                                                     )); | ||||
|                                                 } | ||||
|                                                 None => { | ||||
|                                                     db.admin.send(AdminCommand::SendMessage( | ||||
|                                                         message::MessageEventContent::text_plain( | ||||
|                                                             "PDU not found.", | ||||
|                                                         ), | ||||
|                                                     )); | ||||
|                                                 } | ||||
|                                             } | ||||
|                                         } else { | ||||
|                                             db.admin.send(AdminCommand::SendMessage( | ||||
|                                                 message::MessageEventContent::text_plain( | ||||
|                                                     "Event ID could not be parsed.", | ||||
|                                                 ), | ||||
|                                             )); | ||||
|                                         } | ||||
|                                     } else { | ||||
|                                         db.admin.send(AdminCommand::SendMessage( | ||||
|                                             message::MessageEventContent::text_plain( | ||||
|                                                 "Usage: get_pdu <eventid>", | ||||
|                                             ), | ||||
|                                         )); | ||||
|                                     } | ||||
|                                 } | ||||
|                                 _ => { | ||||
|                                     db.admin.send(AdminCommand::SendMessage( | ||||
|                                         message::MessageEventContent::text_plain(format!( | ||||
|                                             "Command: {}, Args: {:?}", | ||||
|                                             command, args | ||||
|                                             "Unrecognized command: {}", | ||||
|                                             command | ||||
|                                         )), | ||||
|                                     )); | ||||
|                                 } | ||||
|  | @ -2451,4 +2521,10 @@ impl Rooms { | |||
| 
 | ||||
|         Ok(self.userroomid_leftstate.get(&userroom_id)?.is_some()) | ||||
|     } | ||||
| 
 | ||||
|     pub fn auth_chain_cache( | ||||
|         &self, | ||||
|     ) -> std::sync::MutexGuard<'_, LruCache<EventId, HashSet<EventId>>> { | ||||
|         self.auth_chain_cache.lock().unwrap() | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ pub struct Users { | |||
|     pub(super) userid_password: Arc<dyn Tree>, | ||||
|     pub(super) userid_displayname: Arc<dyn Tree>, | ||||
|     pub(super) userid_avatarurl: Arc<dyn Tree>, | ||||
|     pub(super) userid_blurhash: Arc<dyn Tree>, | ||||
|     pub(super) userdeviceid_token: Arc<dyn Tree>, | ||||
|     pub(super) userdeviceid_metadata: Arc<dyn Tree>, // This is also used to check if a device exists
 | ||||
|     pub(super) userid_devicelistversion: Arc<dyn Tree>, // DevicelistVersion = u64
 | ||||
|  | @ -150,7 +151,7 @@ impl Users { | |||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
|     /// Get a the avatar_url of a user.
 | ||||
|     /// Get the avatar_url of a user.
 | ||||
|     pub fn avatar_url(&self, user_id: &UserId) -> Result<Option<MxcUri>> { | ||||
|         self.userid_avatarurl | ||||
|             .get(user_id.as_bytes())? | ||||
|  | @ -174,6 +175,31 @@ impl Users { | |||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
|     /// Get the blurhash of a user.
 | ||||
|     pub fn blurhash(&self, user_id: &UserId) -> Result<Option<String>> { | ||||
|         self.userid_blurhash | ||||
|             .get(user_id.as_bytes())? | ||||
|             .map(|bytes| { | ||||
|                 let s = utils::string_from_bytes(&bytes) | ||||
|                     .map_err(|_| Error::bad_database("Avatar URL in db is invalid."))?; | ||||
| 
 | ||||
|                 Ok(s) | ||||
|             }) | ||||
|             .transpose() | ||||
|     } | ||||
| 
 | ||||
|     /// Sets a new avatar_url or removes it if avatar_url is None.
 | ||||
|     pub fn set_blurhash(&self, user_id: &UserId, blurhash: Option<String>) -> Result<()> { | ||||
|         if let Some(blurhash) = blurhash { | ||||
|             self.userid_blurhash | ||||
|                 .insert(user_id.as_bytes(), blurhash.as_bytes())?; | ||||
|         } else { | ||||
|             self.userid_blurhash.remove(user_id.as_bytes())?; | ||||
|         } | ||||
| 
 | ||||
|         Ok(()) | ||||
|     } | ||||
| 
 | ||||
|     /// Adds a new device to a user.
 | ||||
|     pub fn create_device( | ||||
|         &self, | ||||
|  |  | |||
|  | @ -52,7 +52,7 @@ use ruma::{ | |||
|     ServerSigningKeyId, UserId, | ||||
| }; | ||||
| use std::{ | ||||
|     collections::{btree_map::Entry, BTreeMap, BTreeSet, HashSet}, | ||||
|     collections::{hash_map::Entry, BTreeMap, HashMap, HashSet}, | ||||
|     convert::{TryFrom, TryInto}, | ||||
|     fmt::Debug, | ||||
|     future::Future, | ||||
|  | @ -931,7 +931,7 @@ pub fn handle_incoming_pdu<'a>( | |||
|         ); | ||||
| 
 | ||||
|         // Build map of auth events
 | ||||
|         let mut auth_events = BTreeMap::new(); | ||||
|         let mut auth_events = HashMap::new(); | ||||
|         for id in &incoming_pdu.auth_events { | ||||
|             let auth_event = db | ||||
|                 .rooms | ||||
|  | @ -1097,7 +1097,7 @@ pub fn handle_incoming_pdu<'a>( | |||
|                         Err(_) => return Err("Failed to fetch state events.".to_owned()), | ||||
|                     }; | ||||
| 
 | ||||
|                     let mut state = BTreeMap::new(); | ||||
|                     let mut state = HashMap::new(); | ||||
|                     for pdu in state_vec { | ||||
|                         match state.entry((pdu.kind.clone(), pdu.state_key.clone().ok_or_else(|| "Found non-state pdu in state events.".to_owned())?)) { | ||||
|                             Entry::Vacant(v) => { | ||||
|  | @ -1173,7 +1173,11 @@ pub fn handle_incoming_pdu<'a>( | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         let mut fork_states = BTreeSet::new(); | ||||
|         // Only keep those extremities we don't have in our timeline yet
 | ||||
|         extremities.retain(|id| !matches!(db.rooms.get_non_outlier_pdu_json(id), Ok(Some(_)))); | ||||
| 
 | ||||
|         let mut extremity_statehashes = Vec::new(); | ||||
| 
 | ||||
|         for id in &extremities { | ||||
|             match db | ||||
|                 .rooms | ||||
|  | @ -1181,30 +1185,19 @@ pub fn handle_incoming_pdu<'a>( | |||
|                 .map_err(|_| "Failed to ask db for pdu.".to_owned())? | ||||
|             { | ||||
|                 Some(leaf_pdu) => { | ||||
|                     let pdu_shortstatehash = db | ||||
|                         .rooms | ||||
|                         .pdu_shortstatehash(&leaf_pdu.event_id) | ||||
|                         .map_err(|_| "Failed to ask db for pdu state hash.".to_owned())? | ||||
|                         .ok_or_else(|| { | ||||
|                             error!( | ||||
|                                 "Found extremity pdu with no statehash in db: {:?}", | ||||
|                                 leaf_pdu | ||||
|                             ); | ||||
|                             "Found pdu with no statehash in db.".to_owned() | ||||
|                         })?; | ||||
| 
 | ||||
|                     let mut leaf_state = db | ||||
|                         .rooms | ||||
|                         .state_full(pdu_shortstatehash) | ||||
|                         .map_err(|_| "Failed to ask db for room state.".to_owned())?; | ||||
| 
 | ||||
|                     if let Some(state_key) = &leaf_pdu.state_key { | ||||
|                         // Now it's the state after
 | ||||
|                         let key = (leaf_pdu.kind.clone(), state_key.clone()); | ||||
|                         leaf_state.insert(key, leaf_pdu); | ||||
|                     } | ||||
| 
 | ||||
|                     fork_states.insert(leaf_state); | ||||
|                     extremity_statehashes.push(( | ||||
|                         db.rooms | ||||
|                             .pdu_shortstatehash(&leaf_pdu.event_id) | ||||
|                             .map_err(|_| "Failed to ask db for pdu state hash.".to_owned())? | ||||
|                             .ok_or_else(|| { | ||||
|                                 error!( | ||||
|                                     "Found extremity pdu with no statehash in db: {:?}", | ||||
|                                     leaf_pdu | ||||
|                                 ); | ||||
|                                 "Found pdu with no statehash in db.".to_owned() | ||||
|                             })?, | ||||
|                         Some(leaf_pdu), | ||||
|                     )); | ||||
|                 } | ||||
|                 _ => { | ||||
|                     error!("Missing state snapshot for {:?}", id); | ||||
|  | @ -1218,12 +1211,36 @@ pub fn handle_incoming_pdu<'a>( | |||
|         //     don't just trust a set of state we got from a remote).
 | ||||
| 
 | ||||
|         // We do this by adding the current state to the list of fork states
 | ||||
|         let current_statehash = db | ||||
|             .rooms | ||||
|             .current_shortstatehash(&room_id) | ||||
|             .map_err(|_| "Failed to load current state hash.".to_owned())? | ||||
|             .expect("every room has state"); | ||||
| 
 | ||||
|         let current_state = db | ||||
|             .rooms | ||||
|             .room_state_full(&room_id) | ||||
|             .map_err(|_| "Failed to load room state.".to_owned())?; | ||||
|             .state_full(current_statehash) | ||||
|             .map_err(|_| "Failed to load room state.")?; | ||||
| 
 | ||||
|         fork_states.insert(current_state.clone()); | ||||
|         extremity_statehashes.push((current_statehash.clone(), None)); | ||||
| 
 | ||||
|         let mut fork_states = Vec::new(); | ||||
|         for (statehash, leaf_pdu) in extremity_statehashes { | ||||
|             let mut leaf_state = db | ||||
|                 .rooms | ||||
|                 .state_full(statehash) | ||||
|                 .map_err(|_| "Failed to ask db for room state.".to_owned())?; | ||||
| 
 | ||||
|             if let Some(leaf_pdu) = leaf_pdu { | ||||
|                 if let Some(state_key) = &leaf_pdu.state_key { | ||||
|                     // Now it's the state after
 | ||||
|                     let key = (leaf_pdu.kind.clone(), state_key.clone()); | ||||
|                     leaf_state.insert(key, leaf_pdu); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             fork_states.push(leaf_state); | ||||
|         } | ||||
| 
 | ||||
|         // We also add state after incoming event to the fork states
 | ||||
|         extremities.insert(incoming_pdu.event_id.clone()); | ||||
|  | @ -1234,9 +1251,7 @@ pub fn handle_incoming_pdu<'a>( | |||
|                 incoming_pdu.clone(), | ||||
|             ); | ||||
|         } | ||||
|         fork_states.insert(state_after.clone()); | ||||
| 
 | ||||
|         let fork_states = fork_states.into_iter().collect::<Vec<_>>(); | ||||
|         fork_states.push(state_after.clone()); | ||||
| 
 | ||||
|         let mut update_state = false; | ||||
|         // 14. Use state resolution to find new room state
 | ||||
|  | @ -1254,28 +1269,29 @@ pub fn handle_incoming_pdu<'a>( | |||
|             // We do need to force an update to this room's state
 | ||||
|             update_state = true; | ||||
| 
 | ||||
|             let mut auth_events = vec![]; | ||||
|             for map in &fork_states { | ||||
|                 let state_auth = map | ||||
|                     .values() | ||||
|                     .flat_map(|pdu| pdu.auth_events.clone()) | ||||
|                     .collect(); | ||||
|                 auth_events.push(state_auth); | ||||
|             let fork_states = &fork_states | ||||
|                 .into_iter() | ||||
|                 .map(|map| { | ||||
|                     map.into_iter() | ||||
|                         .map(|(k, v)| (k, v.event_id.clone())) | ||||
|                         .collect::<StateMap<_>>() | ||||
|                 }) | ||||
|                 .collect::<Vec<_>>(); | ||||
| 
 | ||||
|             let mut auth_chain_sets = Vec::new(); | ||||
|             for state in fork_states { | ||||
|                 auth_chain_sets.push( | ||||
|                     get_auth_chain(state.iter().map(|(_, id)| id.clone()).collect(), db) | ||||
|                         .map_err(|_| "Failed to load auth chain.".to_owned())?, | ||||
|                 ); | ||||
|             } | ||||
| 
 | ||||
|             match state_res::StateResolution::resolve( | ||||
|             let state = match state_res::StateResolution::resolve( | ||||
|                 &room_id, | ||||
|                 room_version_id, | ||||
|                 &fork_states | ||||
|                     .into_iter() | ||||
|                     .map(|map| { | ||||
|                         map.into_iter() | ||||
|                             .map(|(k, v)| (k, v.event_id.clone())) | ||||
|                             .collect::<StateMap<_>>() | ||||
|                     }) | ||||
|                     .collect::<Vec<_>>(), | ||||
|                 auth_events, | ||||
|                 &|id| { | ||||
|                 fork_states, | ||||
|                 auth_chain_sets, | ||||
|                 |id| { | ||||
|                     let res = db.rooms.get_pdu(id); | ||||
|                     if let Err(e) = &res { | ||||
|                         error!("LOOK AT ME Failed to fetch event: {}", e); | ||||
|  | @ -1287,7 +1303,8 @@ pub fn handle_incoming_pdu<'a>( | |||
|                 Err(_) => { | ||||
|                     return Err("State resolution failed, either an event could not be found or deserialization".into()); | ||||
|                 } | ||||
|             } | ||||
|             }; | ||||
|             state | ||||
|         }; | ||||
| 
 | ||||
|         // 13. Check if the event passes auth based on the "current state" of the room, if not "soft fail" it
 | ||||
|  | @ -1706,6 +1723,45 @@ async fn append_incoming_pdu( | |||
|     Ok(pdu_id) | ||||
| } | ||||
| 
 | ||||
| fn get_auth_chain(starting_events: Vec<EventId>, db: &Database) -> Result<HashSet<EventId>> { | ||||
|     let mut full_auth_chain = HashSet::new(); | ||||
| 
 | ||||
|     let mut cache = db.rooms.auth_chain_cache(); | ||||
|     for event_id in starting_events { | ||||
|         let auth_chain = if let Some(cached) = cache.get_mut(&event_id) { | ||||
|             cached.clone() | ||||
|         } else { | ||||
|             drop(cache); | ||||
|             let auth_chain = get_auth_chain_recursive(&event_id, db)?; | ||||
| 
 | ||||
|             cache = db.rooms.auth_chain_cache(); | ||||
| 
 | ||||
|             cache.insert(event_id, auth_chain.clone()); | ||||
| 
 | ||||
|             auth_chain | ||||
|         }; | ||||
| 
 | ||||
|         full_auth_chain.extend(auth_chain); | ||||
|     } | ||||
| 
 | ||||
|     Ok(full_auth_chain) | ||||
| } | ||||
| 
 | ||||
| fn get_auth_chain_recursive(event_id: &EventId, db: &Database) -> Result<HashSet<EventId>> { | ||||
|     let mut auth_chain = HashSet::new(); | ||||
| 
 | ||||
|     if let Some(pdu) = db.rooms.get_pdu(&event_id)? { | ||||
|         auth_chain.extend(pdu.auth_events.iter().cloned()); | ||||
|         for auth_event in &pdu.auth_events { | ||||
|             auth_chain.extend(get_auth_chain_recursive(&auth_event, db)?); | ||||
|         } | ||||
|     } else { | ||||
|         warn!("Could not find pdu mentioned in auth events."); | ||||
|     } | ||||
| 
 | ||||
|     Ok(auth_chain) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|     feature = "conduit_bin", | ||||
|     get("/_matrix/federation/v1/event/<_>", data = "<body>") | ||||
|  | @ -1793,35 +1849,20 @@ pub fn get_event_authorization_route( | |||
|         return Err(Error::bad_config("Federation is disabled.")); | ||||
|     } | ||||
| 
 | ||||
|     let mut auth_chain = Vec::new(); | ||||
|     let mut auth_chain_ids = BTreeSet::<EventId>::new(); | ||||
|     let mut todo = BTreeSet::new(); | ||||
|     todo.insert(body.event_id.clone()); | ||||
|     let auth_chain_ids = get_auth_chain(vec![body.event_id.clone()], &db)?; | ||||
| 
 | ||||
|     while let Some(event_id) = todo.iter().next().cloned() { | ||||
|         if let Some(pdu) = db.rooms.get_pdu(&event_id)? { | ||||
|             todo.extend( | ||||
|                 pdu.auth_events | ||||
|                     .clone() | ||||
|                     .into_iter() | ||||
|                     .collect::<BTreeSet<_>>() | ||||
|                     .difference(&auth_chain_ids) | ||||
|                     .cloned(), | ||||
|             ); | ||||
|             auth_chain_ids.extend(pdu.auth_events.clone().into_iter()); | ||||
| 
 | ||||
|             let pdu_json = PduEvent::convert_to_outgoing_federation_event( | ||||
|                 db.rooms.get_pdu_json(&event_id)?.unwrap(), | ||||
|             ); | ||||
|             auth_chain.push(pdu_json); | ||||
|         } else { | ||||
|             warn!("Could not find pdu mentioned in auth events."); | ||||
|         } | ||||
| 
 | ||||
|         todo.remove(&event_id); | ||||
|     Ok(get_event_authorization::v1::Response { | ||||
|         auth_chain: auth_chain_ids | ||||
|             .into_iter() | ||||
|             .map(|id| { | ||||
|                 Ok::<_, Error>(PduEvent::convert_to_outgoing_federation_event( | ||||
|                     db.rooms.get_pdu_json(&id)?.unwrap(), | ||||
|                 )) | ||||
|             }) | ||||
|             .filter_map(|r| r.ok()) | ||||
|             .collect(), | ||||
|     } | ||||
| 
 | ||||
|     Ok(get_event_authorization::v1::Response { auth_chain }.into()) | ||||
|     .into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  | @ -1856,35 +1897,21 @@ pub fn get_room_state_route( | |||
|         }) | ||||
|         .collect(); | ||||
| 
 | ||||
|     let mut auth_chain = Vec::new(); | ||||
|     let mut auth_chain_ids = BTreeSet::<EventId>::new(); | ||||
|     let mut todo = BTreeSet::new(); | ||||
|     todo.insert(body.event_id.clone()); | ||||
|     let auth_chain_ids = get_auth_chain(vec![body.event_id.clone()], &db)?; | ||||
| 
 | ||||
|     while let Some(event_id) = todo.iter().next().cloned() { | ||||
|         if let Some(pdu) = db.rooms.get_pdu(&event_id)? { | ||||
|             todo.extend( | ||||
|                 pdu.auth_events | ||||
|                     .clone() | ||||
|                     .into_iter() | ||||
|                     .collect::<BTreeSet<_>>() | ||||
|                     .difference(&auth_chain_ids) | ||||
|                     .cloned(), | ||||
|             ); | ||||
|             auth_chain_ids.extend(pdu.auth_events.clone().into_iter()); | ||||
| 
 | ||||
|             let pdu_json = PduEvent::convert_to_outgoing_federation_event( | ||||
|                 db.rooms.get_pdu_json(&event_id)?.unwrap(), | ||||
|             ); | ||||
|             auth_chain.push(pdu_json); | ||||
|         } else { | ||||
|             warn!("Could not find pdu mentioned in auth events."); | ||||
|         } | ||||
| 
 | ||||
|         todo.remove(&event_id); | ||||
|     Ok(get_room_state::v1::Response { | ||||
|         auth_chain: auth_chain_ids | ||||
|             .into_iter() | ||||
|             .map(|id| { | ||||
|                 Ok::<_, Error>(PduEvent::convert_to_outgoing_federation_event( | ||||
|                     db.rooms.get_pdu_json(&id)?.unwrap(), | ||||
|                 )) | ||||
|             }) | ||||
|             .filter_map(|r| r.ok()) | ||||
|             .collect(), | ||||
|         pdus, | ||||
|     } | ||||
| 
 | ||||
|     Ok(get_room_state::v1::Response { auth_chain, pdus }.into()) | ||||
|     .into()) | ||||
| } | ||||
| 
 | ||||
| #[cfg_attr(
 | ||||
|  | @ -1914,27 +1941,7 @@ pub fn get_room_state_ids_route( | |||
|         .into_iter() | ||||
|         .collect(); | ||||
| 
 | ||||
|     let mut auth_chain_ids = BTreeSet::<EventId>::new(); | ||||
|     let mut todo = BTreeSet::new(); | ||||
|     todo.insert(body.event_id.clone()); | ||||
| 
 | ||||
|     while let Some(event_id) = todo.iter().next().cloned() { | ||||
|         if let Some(pdu) = db.rooms.get_pdu(&event_id)? { | ||||
|             todo.extend( | ||||
|                 pdu.auth_events | ||||
|                     .clone() | ||||
|                     .into_iter() | ||||
|                     .collect::<BTreeSet<_>>() | ||||
|                     .difference(&auth_chain_ids) | ||||
|                     .cloned(), | ||||
|             ); | ||||
|             auth_chain_ids.extend(pdu.auth_events.clone().into_iter()); | ||||
|         } else { | ||||
|             warn!("Could not find pdu mentioned in auth events."); | ||||
|         } | ||||
| 
 | ||||
|         todo.remove(&event_id); | ||||
|     } | ||||
|     let auth_chain_ids = get_auth_chain(vec![body.event_id.clone()], &db)?; | ||||
| 
 | ||||
|     Ok(get_room_state_ids::v1::Response { | ||||
|         auth_chain_ids: auth_chain_ids.into_iter().collect(), | ||||
|  | @ -2011,6 +2018,7 @@ pub fn create_join_event_template_route( | |||
| 
 | ||||
|     let content = serde_json::to_value(MemberEventContent { | ||||
|         avatar_url: None, | ||||
|         blurhash: None, | ||||
|         displayname: None, | ||||
|         is_direct: None, | ||||
|         membership: MembershipState::Join, | ||||
|  | @ -2190,27 +2198,7 @@ pub async fn create_join_event_route( | |||
|     drop(mutex_lock); | ||||
| 
 | ||||
|     let state_ids = db.rooms.state_full_ids(shortstatehash)?; | ||||
| 
 | ||||
|     let mut auth_chain_ids = BTreeSet::<EventId>::new(); | ||||
|     let mut todo = state_ids.iter().cloned().collect::<BTreeSet<_>>(); | ||||
| 
 | ||||
|     while let Some(event_id) = todo.iter().next().cloned() { | ||||
|         if let Some(pdu) = db.rooms.get_pdu(&event_id)? { | ||||
|             todo.extend( | ||||
|                 pdu.auth_events | ||||
|                     .clone() | ||||
|                     .into_iter() | ||||
|                     .collect::<BTreeSet<_>>() | ||||
|                     .difference(&auth_chain_ids) | ||||
|                     .cloned(), | ||||
|             ); | ||||
|             auth_chain_ids.extend(pdu.auth_events.clone().into_iter()); | ||||
|         } else { | ||||
|             warn!("Could not find pdu mentioned in auth events."); | ||||
|         } | ||||
| 
 | ||||
|         todo.remove(&event_id); | ||||
|     } | ||||
|     let auth_chain_ids = get_auth_chain(state_ids.iter().cloned().collect(), &db)?; | ||||
| 
 | ||||
|     for server in db | ||||
|         .rooms | ||||
|  | @ -2430,19 +2418,25 @@ pub fn get_profile_information_route( | |||
| 
 | ||||
|     let mut displayname = None; | ||||
|     let mut avatar_url = None; | ||||
|     let mut blurhash = None; | ||||
| 
 | ||||
|     match &body.field { | ||||
|         // TODO: what to do with custom
 | ||||
|         Some(ProfileField::_Custom(_s)) => {} | ||||
|         Some(ProfileField::DisplayName) => displayname = db.users.displayname(&body.user_id)?, | ||||
|         Some(ProfileField::AvatarUrl) => avatar_url = db.users.avatar_url(&body.user_id)?, | ||||
|         Some(ProfileField::AvatarUrl) => { | ||||
|             avatar_url = db.users.avatar_url(&body.user_id)?; | ||||
|             blurhash = db.users.blurhash(&body.user_id)? | ||||
|         } | ||||
|         // TODO: what to do with custom
 | ||||
|         Some(_) => {} | ||||
|         None => { | ||||
|             displayname = db.users.displayname(&body.user_id)?; | ||||
|             avatar_url = db.users.avatar_url(&body.user_id)?; | ||||
|             blurhash = db.users.blurhash(&body.user_id)?; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     Ok(get_profile_information::v1::Response { | ||||
|         blurhash, | ||||
|         displayname, | ||||
|         avatar_url, | ||||
|     } | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue