|
|
|
@ -5,15 +5,18 @@ use std::{ |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
use log::{debug, warn}; |
|
|
|
use log::{debug, warn}; |
|
|
|
use rocket::{get, options, post, put, State}; |
|
|
|
use rocket::{delete, get, options, post, put, State}; |
|
|
|
use ruma_client_api::{ |
|
|
|
use ruma_client_api::{ |
|
|
|
error::{Error, ErrorKind}, |
|
|
|
error::{Error, ErrorKind}, |
|
|
|
r0::{ |
|
|
|
r0::{ |
|
|
|
account::{get_username_availability, register}, |
|
|
|
account::{get_username_availability, register}, |
|
|
|
alias::get_alias, |
|
|
|
alias::{create_alias, delete_alias, get_alias}, |
|
|
|
capabilities::get_capabilities, |
|
|
|
capabilities::get_capabilities, |
|
|
|
config::{get_global_account_data, set_global_account_data}, |
|
|
|
config::{get_global_account_data, set_global_account_data}, |
|
|
|
directory::{self, get_public_rooms, get_public_rooms_filtered}, |
|
|
|
directory::{ |
|
|
|
|
|
|
|
self, get_public_rooms, get_public_rooms_filtered, get_room_visibility, |
|
|
|
|
|
|
|
set_room_visibility, |
|
|
|
|
|
|
|
}, |
|
|
|
filter::{self, create_filter, get_filter}, |
|
|
|
filter::{self, create_filter, get_filter}, |
|
|
|
keys::{claim_keys, get_keys, upload_keys}, |
|
|
|
keys::{claim_keys, get_keys, upload_keys}, |
|
|
|
media::{create_content, get_content, get_content_thumbnail, get_media_config}, |
|
|
|
media::{create_content, get_content, get_content_thumbnail, get_media_config}, |
|
|
|
@ -28,6 +31,7 @@ use ruma_client_api::{ |
|
|
|
}, |
|
|
|
}, |
|
|
|
push::{get_pushrules_all, set_pushrule, set_pushrule_enabled}, |
|
|
|
push::{get_pushrules_all, set_pushrule, set_pushrule_enabled}, |
|
|
|
read_marker::set_read_marker, |
|
|
|
read_marker::set_read_marker, |
|
|
|
|
|
|
|
redact::redact_event, |
|
|
|
room::{self, create_room}, |
|
|
|
room::{self, create_room}, |
|
|
|
session::{get_login_types, login, logout}, |
|
|
|
session::{get_login_types, login, logout}, |
|
|
|
state::{ |
|
|
|
state::{ |
|
|
|
@ -45,10 +49,10 @@ use ruma_client_api::{ |
|
|
|
}; |
|
|
|
}; |
|
|
|
use ruma_events::{ |
|
|
|
use ruma_events::{ |
|
|
|
collections::only::Event as EduEvent, |
|
|
|
collections::only::Event as EduEvent, |
|
|
|
room::{guest_access, history_visibility, join_rules, member}, |
|
|
|
room::{canonical_alias, guest_access, history_visibility, join_rules, member, redaction}, |
|
|
|
EventJson, EventType, |
|
|
|
EventJson, EventType, |
|
|
|
}; |
|
|
|
}; |
|
|
|
use ruma_identifiers::{RoomId, RoomVersionId, UserId}; |
|
|
|
use ruma_identifiers::{RoomAliasId, RoomId, RoomVersionId, UserId}; |
|
|
|
use serde_json::{json, value::RawValue}; |
|
|
|
use serde_json::{json, value::RawValue}; |
|
|
|
|
|
|
|
|
|
|
|
use crate::{server_server, utils, Database, MatrixResult, Ruma}; |
|
|
|
use crate::{server_server, utils, Database, MatrixResult, Ruma}; |
|
|
|
@ -517,6 +521,7 @@ pub fn set_displayname_route( |
|
|
|
.unwrap(), |
|
|
|
.unwrap(), |
|
|
|
None, |
|
|
|
None, |
|
|
|
Some(user_id.to_string()), |
|
|
|
Some(user_id.to_string()), |
|
|
|
|
|
|
|
None, |
|
|
|
&db.globals, |
|
|
|
&db.globals, |
|
|
|
) |
|
|
|
) |
|
|
|
.unwrap(); |
|
|
|
.unwrap(); |
|
|
|
@ -564,7 +569,7 @@ pub fn set_avatar_url_route( |
|
|
|
) -> MatrixResult<set_avatar_url::Response> { |
|
|
|
) -> MatrixResult<set_avatar_url::Response> { |
|
|
|
let user_id = body.user_id.as_ref().expect("user is authenticated"); |
|
|
|
let user_id = body.user_id.as_ref().expect("user is authenticated"); |
|
|
|
|
|
|
|
|
|
|
|
if let avatar_url = &body.avatar_url { |
|
|
|
if let Some(avatar_url) = &body.avatar_url { |
|
|
|
if !avatar_url.starts_with("mxc://") { |
|
|
|
if !avatar_url.starts_with("mxc://") { |
|
|
|
debug!("Request contains an invalid avatar_url."); |
|
|
|
debug!("Request contains an invalid avatar_url."); |
|
|
|
return MatrixResult(Err(Error { |
|
|
|
return MatrixResult(Err(Error { |
|
|
|
@ -579,7 +584,7 @@ pub fn set_avatar_url_route( |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
db.users |
|
|
|
db.users |
|
|
|
.set_avatar_url(&user_id, Some(body.avatar_url.clone())) |
|
|
|
.set_avatar_url(&user_id, body.avatar_url.clone()) |
|
|
|
.unwrap(); |
|
|
|
.unwrap(); |
|
|
|
|
|
|
|
|
|
|
|
// Send a new membership event into all joined rooms
|
|
|
|
// Send a new membership event into all joined rooms
|
|
|
|
@ -591,7 +596,7 @@ pub fn set_avatar_url_route( |
|
|
|
user_id.clone(), |
|
|
|
user_id.clone(), |
|
|
|
EventType::RoomMember, |
|
|
|
EventType::RoomMember, |
|
|
|
serde_json::to_value(ruma_events::room::member::MemberEventContent { |
|
|
|
serde_json::to_value(ruma_events::room::member::MemberEventContent { |
|
|
|
avatar_url: Some(body.avatar_url.clone()), |
|
|
|
avatar_url: body.avatar_url.clone(), |
|
|
|
..serde_json::from_value::<EventJson<_>>( |
|
|
|
..serde_json::from_value::<EventJson<_>>( |
|
|
|
db.rooms |
|
|
|
db.rooms |
|
|
|
.room_state(&room_id) |
|
|
|
.room_state(&room_id) |
|
|
|
@ -608,6 +613,7 @@ pub fn set_avatar_url_route( |
|
|
|
.unwrap(), |
|
|
|
.unwrap(), |
|
|
|
None, |
|
|
|
None, |
|
|
|
Some(user_id.to_string()), |
|
|
|
Some(user_id.to_string()), |
|
|
|
|
|
|
|
None, |
|
|
|
&db.globals, |
|
|
|
&db.globals, |
|
|
|
) |
|
|
|
) |
|
|
|
.unwrap(); |
|
|
|
.unwrap(); |
|
|
|
@ -669,7 +675,7 @@ pub fn get_profile_route( |
|
|
|
MatrixResult(Err(Error { |
|
|
|
MatrixResult(Err(Error { |
|
|
|
kind: ErrorKind::NotFound, |
|
|
|
kind: ErrorKind::NotFound, |
|
|
|
message: "Profile was not found.".to_owned(), |
|
|
|
message: "Profile was not found.".to_owned(), |
|
|
|
status_code: http::StatusCode::BAD_REQUEST, |
|
|
|
status_code: http::StatusCode::NOT_FOUND, |
|
|
|
})) |
|
|
|
})) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -906,8 +912,32 @@ pub fn create_room_route( |
|
|
|
let room_id = RoomId::new(db.globals.server_name()).expect("host is valid"); |
|
|
|
let room_id = RoomId::new(db.globals.server_name()).expect("host is valid"); |
|
|
|
let user_id = body.user_id.as_ref().expect("user is authenticated"); |
|
|
|
let user_id = body.user_id.as_ref().expect("user is authenticated"); |
|
|
|
|
|
|
|
|
|
|
|
// TODO: Create alias and check if it already exists
|
|
|
|
let alias = if let Some(localpart) = &body.room_alias_name { |
|
|
|
|
|
|
|
// TODO: Check for invalid characters and maximum length
|
|
|
|
|
|
|
|
if let Ok(alias) = |
|
|
|
|
|
|
|
RoomAliasId::try_from(format!("#{}:{}", localpart, db.globals.server_name())) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if db.rooms.id_from_alias(&alias).unwrap().is_some() { |
|
|
|
|
|
|
|
return MatrixResult(Err(Error { |
|
|
|
|
|
|
|
kind: ErrorKind::Unknown, |
|
|
|
|
|
|
|
message: "Alias already exists.".to_owned(), |
|
|
|
|
|
|
|
status_code: http::StatusCode::BAD_REQUEST, |
|
|
|
|
|
|
|
})); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Some(alias) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
return MatrixResult(Err(Error { |
|
|
|
|
|
|
|
kind: ErrorKind::Unknown, |
|
|
|
|
|
|
|
message: "Invalid alias.".to_owned(), |
|
|
|
|
|
|
|
status_code: http::StatusCode::BAD_REQUEST, |
|
|
|
|
|
|
|
})); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
None |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1. The room create event
|
|
|
|
db.rooms |
|
|
|
db.rooms |
|
|
|
.append_pdu( |
|
|
|
.append_pdu( |
|
|
|
room_id.clone(), |
|
|
|
room_id.clone(), |
|
|
|
@ -915,21 +945,22 @@ pub fn create_room_route( |
|
|
|
EventType::RoomCreate, |
|
|
|
EventType::RoomCreate, |
|
|
|
serde_json::to_value(ruma_events::room::create::CreateEventContent { |
|
|
|
serde_json::to_value(ruma_events::room::create::CreateEventContent { |
|
|
|
creator: user_id.clone(), |
|
|
|
creator: user_id.clone(), |
|
|
|
federate: body |
|
|
|
federate: body.creation_content.as_ref().map_or(true, |c| c.federate), |
|
|
|
|
|
|
|
predecessor: body |
|
|
|
.creation_content |
|
|
|
.creation_content |
|
|
|
.and_then(|c| c.federate) |
|
|
|
.as_ref() |
|
|
|
.unwrap_or(true), |
|
|
|
.and_then(|c| c.predecessor.clone()), |
|
|
|
predecessor: None, // TODO: Check creation_content.predecessor once ruma has that
|
|
|
|
|
|
|
|
room_version: RoomVersionId::version_5(), |
|
|
|
room_version: RoomVersionId::version_5(), |
|
|
|
}) |
|
|
|
}) |
|
|
|
.unwrap(), |
|
|
|
.unwrap(), |
|
|
|
None, |
|
|
|
None, |
|
|
|
Some("".to_owned()), |
|
|
|
Some("".to_owned()), |
|
|
|
|
|
|
|
None, |
|
|
|
&db.globals, |
|
|
|
&db.globals, |
|
|
|
) |
|
|
|
) |
|
|
|
.unwrap(); |
|
|
|
.unwrap(); |
|
|
|
|
|
|
|
|
|
|
|
// Join room
|
|
|
|
// 2. Let the room creator join
|
|
|
|
db.rooms |
|
|
|
db.rooms |
|
|
|
.append_pdu( |
|
|
|
.append_pdu( |
|
|
|
room_id.clone(), |
|
|
|
room_id.clone(), |
|
|
|
@ -945,6 +976,7 @@ pub fn create_room_route( |
|
|
|
.unwrap(), |
|
|
|
.unwrap(), |
|
|
|
None, |
|
|
|
None, |
|
|
|
Some(user_id.to_string()), |
|
|
|
Some(user_id.to_string()), |
|
|
|
|
|
|
|
None, |
|
|
|
&db.globals, |
|
|
|
&db.globals, |
|
|
|
) |
|
|
|
) |
|
|
|
.unwrap(); |
|
|
|
.unwrap(); |
|
|
|
@ -956,7 +988,7 @@ pub fn create_room_route( |
|
|
|
room::Visibility::Public => create_room::RoomPreset::PublicChat, |
|
|
|
room::Visibility::Public => create_room::RoomPreset::PublicChat, |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// 0. Power levels
|
|
|
|
// 3. Power levels
|
|
|
|
let mut users = BTreeMap::new(); |
|
|
|
let mut users = BTreeMap::new(); |
|
|
|
users.insert(user_id.clone(), 100.into()); |
|
|
|
users.insert(user_id.clone(), 100.into()); |
|
|
|
for invite_user_id in &body.invite { |
|
|
|
for invite_user_id in &body.invite { |
|
|
|
@ -991,12 +1023,13 @@ pub fn create_room_route( |
|
|
|
power_levels_content, |
|
|
|
power_levels_content, |
|
|
|
None, |
|
|
|
None, |
|
|
|
Some("".to_owned()), |
|
|
|
Some("".to_owned()), |
|
|
|
|
|
|
|
None, |
|
|
|
&db.globals, |
|
|
|
&db.globals, |
|
|
|
) |
|
|
|
) |
|
|
|
.unwrap(); |
|
|
|
.unwrap(); |
|
|
|
|
|
|
|
|
|
|
|
// 1. Events set by preset
|
|
|
|
// 4. Events set by preset
|
|
|
|
// 1.1 Join Rules
|
|
|
|
// 4.1 Join Rules
|
|
|
|
db.rooms |
|
|
|
db.rooms |
|
|
|
.append_pdu( |
|
|
|
.append_pdu( |
|
|
|
room_id.clone(), |
|
|
|
room_id.clone(), |
|
|
|
@ -1016,11 +1049,12 @@ pub fn create_room_route( |
|
|
|
}, |
|
|
|
}, |
|
|
|
None, |
|
|
|
None, |
|
|
|
Some("".to_owned()), |
|
|
|
Some("".to_owned()), |
|
|
|
|
|
|
|
None, |
|
|
|
&db.globals, |
|
|
|
&db.globals, |
|
|
|
) |
|
|
|
) |
|
|
|
.unwrap(); |
|
|
|
.unwrap(); |
|
|
|
|
|
|
|
|
|
|
|
// 1.2 History Visibility
|
|
|
|
// 4.2 History Visibility
|
|
|
|
db.rooms |
|
|
|
db.rooms |
|
|
|
.append_pdu( |
|
|
|
.append_pdu( |
|
|
|
room_id.clone(), |
|
|
|
room_id.clone(), |
|
|
|
@ -1032,11 +1066,12 @@ pub fn create_room_route( |
|
|
|
.unwrap(), |
|
|
|
.unwrap(), |
|
|
|
None, |
|
|
|
None, |
|
|
|
Some("".to_owned()), |
|
|
|
Some("".to_owned()), |
|
|
|
|
|
|
|
None, |
|
|
|
&db.globals, |
|
|
|
&db.globals, |
|
|
|
) |
|
|
|
) |
|
|
|
.unwrap(); |
|
|
|
.unwrap(); |
|
|
|
|
|
|
|
|
|
|
|
// 1.3 Guest Access
|
|
|
|
// 4.3 Guest Access
|
|
|
|
db.rooms |
|
|
|
db.rooms |
|
|
|
.append_pdu( |
|
|
|
.append_pdu( |
|
|
|
room_id.clone(), |
|
|
|
room_id.clone(), |
|
|
|
@ -1056,11 +1091,12 @@ pub fn create_room_route( |
|
|
|
}, |
|
|
|
}, |
|
|
|
None, |
|
|
|
None, |
|
|
|
Some("".to_owned()), |
|
|
|
Some("".to_owned()), |
|
|
|
|
|
|
|
None, |
|
|
|
&db.globals, |
|
|
|
&db.globals, |
|
|
|
) |
|
|
|
) |
|
|
|
.unwrap(); |
|
|
|
.unwrap(); |
|
|
|
|
|
|
|
|
|
|
|
// 2. Events listed in initial_state
|
|
|
|
// 5. Events listed in initial_state
|
|
|
|
for create_room::InitialStateEvent { |
|
|
|
for create_room::InitialStateEvent { |
|
|
|
event_type, |
|
|
|
event_type, |
|
|
|
state_key, |
|
|
|
state_key, |
|
|
|
@ -1071,16 +1107,17 @@ pub fn create_room_route( |
|
|
|
.append_pdu( |
|
|
|
.append_pdu( |
|
|
|
room_id.clone(), |
|
|
|
room_id.clone(), |
|
|
|
user_id.clone(), |
|
|
|
user_id.clone(), |
|
|
|
EventType::from(event_type), |
|
|
|
event_type.clone(), |
|
|
|
serde_json::from_str(content.get()).unwrap(), |
|
|
|
serde_json::from_str(content.get()).unwrap(), |
|
|
|
None, |
|
|
|
None, |
|
|
|
state_key.clone(), |
|
|
|
state_key.clone(), |
|
|
|
|
|
|
|
None, |
|
|
|
&db.globals, |
|
|
|
&db.globals, |
|
|
|
) |
|
|
|
) |
|
|
|
.unwrap(); |
|
|
|
.unwrap(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 3. Events implied by name and topic
|
|
|
|
// 6. Events implied by name and topic
|
|
|
|
if let Some(name) = &body.name { |
|
|
|
if let Some(name) = &body.name { |
|
|
|
db.rooms |
|
|
|
db.rooms |
|
|
|
.append_pdu( |
|
|
|
.append_pdu( |
|
|
|
@ -1093,6 +1130,7 @@ pub fn create_room_route( |
|
|
|
.unwrap(), |
|
|
|
.unwrap(), |
|
|
|
None, |
|
|
|
None, |
|
|
|
Some("".to_owned()), |
|
|
|
Some("".to_owned()), |
|
|
|
|
|
|
|
None, |
|
|
|
&db.globals, |
|
|
|
&db.globals, |
|
|
|
) |
|
|
|
) |
|
|
|
.unwrap(); |
|
|
|
.unwrap(); |
|
|
|
@ -1110,12 +1148,13 @@ pub fn create_room_route( |
|
|
|
.unwrap(), |
|
|
|
.unwrap(), |
|
|
|
None, |
|
|
|
None, |
|
|
|
Some("".to_owned()), |
|
|
|
Some("".to_owned()), |
|
|
|
|
|
|
|
None, |
|
|
|
&db.globals, |
|
|
|
&db.globals, |
|
|
|
) |
|
|
|
) |
|
|
|
.unwrap(); |
|
|
|
.unwrap(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 4. Events implied by invite (and TODO: invite_3pid)
|
|
|
|
// 7. Events implied by invite (and TODO: invite_3pid)
|
|
|
|
for user in &body.invite { |
|
|
|
for user in &body.invite { |
|
|
|
db.rooms |
|
|
|
db.rooms |
|
|
|
.append_pdu( |
|
|
|
.append_pdu( |
|
|
|
@ -1132,43 +1171,119 @@ pub fn create_room_route( |
|
|
|
.unwrap(), |
|
|
|
.unwrap(), |
|
|
|
None, |
|
|
|
None, |
|
|
|
Some(user.to_string()), |
|
|
|
Some(user.to_string()), |
|
|
|
|
|
|
|
None, |
|
|
|
&db.globals, |
|
|
|
&db.globals, |
|
|
|
) |
|
|
|
) |
|
|
|
.unwrap(); |
|
|
|
.unwrap(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Homeserver specific stuff
|
|
|
|
|
|
|
|
if let Some(alias) = alias { |
|
|
|
|
|
|
|
db.rooms |
|
|
|
|
|
|
|
.set_alias(&alias, Some(&room_id), &db.globals) |
|
|
|
|
|
|
|
.unwrap(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if let Some(room::Visibility::Public) = body.visibility { |
|
|
|
|
|
|
|
db.rooms.set_public(&room_id, true).unwrap(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
MatrixResult(Ok(create_room::Response { room_id })) |
|
|
|
MatrixResult(Ok(create_room::Response { room_id })) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[put(
|
|
|
|
|
|
|
|
"/_matrix/client/r0/rooms/<_room_id>/redact/<_event_id>/<_txn_id>", |
|
|
|
|
|
|
|
data = "<body>" |
|
|
|
|
|
|
|
)] |
|
|
|
|
|
|
|
pub fn redact_event_route( |
|
|
|
|
|
|
|
db: State<'_, Database>, |
|
|
|
|
|
|
|
body: Ruma<redact_event::Request>, |
|
|
|
|
|
|
|
_room_id: String, |
|
|
|
|
|
|
|
_event_id: String, |
|
|
|
|
|
|
|
_txn_id: String, |
|
|
|
|
|
|
|
) -> MatrixResult<redact_event::Response> { |
|
|
|
|
|
|
|
let user_id = body.user_id.as_ref().expect("user is authenticated"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if let Ok(event_id) = db.rooms.append_pdu( |
|
|
|
|
|
|
|
body.room_id.clone(), |
|
|
|
|
|
|
|
user_id.clone(), |
|
|
|
|
|
|
|
EventType::RoomRedaction, |
|
|
|
|
|
|
|
serde_json::to_value(redaction::RedactionEventContent { |
|
|
|
|
|
|
|
reason: body.reason.clone(), |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
.unwrap(), |
|
|
|
|
|
|
|
None, |
|
|
|
|
|
|
|
None, |
|
|
|
|
|
|
|
Some(body.event_id.clone()), |
|
|
|
|
|
|
|
&db.globals, |
|
|
|
|
|
|
|
) { |
|
|
|
|
|
|
|
MatrixResult(Ok(redact_event::Response { event_id })) |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
MatrixResult(Err(Error { |
|
|
|
|
|
|
|
kind: ErrorKind::Unknown, |
|
|
|
|
|
|
|
message: "Failed to redact event.".to_owned(), |
|
|
|
|
|
|
|
status_code: http::StatusCode::BAD_REQUEST, |
|
|
|
|
|
|
|
})) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[put("/_matrix/client/r0/directory/room/<_room_alias>", data = "<body>")] |
|
|
|
|
|
|
|
pub fn create_alias_route( |
|
|
|
|
|
|
|
db: State<'_, Database>, |
|
|
|
|
|
|
|
body: Ruma<create_alias::Request>, |
|
|
|
|
|
|
|
_room_alias: String, |
|
|
|
|
|
|
|
) -> MatrixResult<create_alias::Response> { |
|
|
|
|
|
|
|
if db.rooms.id_from_alias(&body.room_alias).unwrap().is_some() { |
|
|
|
|
|
|
|
return MatrixResult(Err(Error { |
|
|
|
|
|
|
|
kind: ErrorKind::Unknown, |
|
|
|
|
|
|
|
message: "Alias already exists".to_owned(), |
|
|
|
|
|
|
|
status_code: http::StatusCode::BAD_REQUEST, |
|
|
|
|
|
|
|
})); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db.rooms |
|
|
|
|
|
|
|
.set_alias(&body.room_alias, Some(&body.room_id), &db.globals) |
|
|
|
|
|
|
|
.unwrap(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MatrixResult(Ok(create_alias::Response)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[delete("/_matrix/client/r0/directory/room/<_room_alias>", data = "<body>")] |
|
|
|
|
|
|
|
pub fn delete_alias_route( |
|
|
|
|
|
|
|
db: State<'_, Database>, |
|
|
|
|
|
|
|
body: Ruma<delete_alias::Request>, |
|
|
|
|
|
|
|
_room_alias: String, |
|
|
|
|
|
|
|
) -> MatrixResult<delete_alias::Response> { |
|
|
|
|
|
|
|
db.rooms |
|
|
|
|
|
|
|
.set_alias(&body.room_alias, None, &db.globals) |
|
|
|
|
|
|
|
.unwrap(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MatrixResult(Ok(delete_alias::Response)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[get("/_matrix/client/r0/directory/room/<_room_alias>", data = "<body>")] |
|
|
|
#[get("/_matrix/client/r0/directory/room/<_room_alias>", data = "<body>")] |
|
|
|
pub fn get_alias_route( |
|
|
|
pub fn get_alias_route( |
|
|
|
db: State<'_, Database>, |
|
|
|
db: State<'_, Database>, |
|
|
|
body: Ruma<get_alias::Request>, |
|
|
|
body: Ruma<get_alias::Request>, |
|
|
|
_room_alias: String, |
|
|
|
_room_alias: String, |
|
|
|
) -> MatrixResult<get_alias::Response> { |
|
|
|
) -> MatrixResult<get_alias::Response> { |
|
|
|
warn!("TODO: get_alias_route"); |
|
|
|
if body.room_alias.server_name() == db.globals.server_name() { |
|
|
|
let room_id = if body.room_alias.server_name() == db.globals.server_name() { |
|
|
|
if let Some(room_id) = db.rooms.id_from_alias(&body.room_alias).unwrap() { |
|
|
|
match body.room_alias.alias() { |
|
|
|
MatrixResult(Ok(get_alias::Response { |
|
|
|
"conduit" => "!lgOCCXQKtXOAPlAlG5:conduit.rs", |
|
|
|
room_id, |
|
|
|
_ => { |
|
|
|
servers: vec![db.globals.server_name().to_owned()], |
|
|
|
|
|
|
|
})) |
|
|
|
|
|
|
|
} else { |
|
|
|
debug!("Room alias not found."); |
|
|
|
debug!("Room alias not found."); |
|
|
|
return MatrixResult(Err(Error { |
|
|
|
return MatrixResult(Err(Error { |
|
|
|
kind: ErrorKind::NotFound, |
|
|
|
kind: ErrorKind::NotFound, |
|
|
|
message: "Room not found.".to_owned(), |
|
|
|
message: "Room with alias not found.".to_owned(), |
|
|
|
status_code: http::StatusCode::BAD_REQUEST, |
|
|
|
status_code: http::StatusCode::BAD_REQUEST, |
|
|
|
})); |
|
|
|
})); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
todo!("ask remote server"); |
|
|
|
todo!("ask remote server"); |
|
|
|
} |
|
|
|
} |
|
|
|
.try_into() |
|
|
|
|
|
|
|
.unwrap(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MatrixResult(Ok(get_alias::Response { |
|
|
|
|
|
|
|
room_id, |
|
|
|
|
|
|
|
servers: vec!["conduit.rs".to_owned()], |
|
|
|
|
|
|
|
})) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[post("/_matrix/client/r0/rooms/<_room_id>/join", data = "<body>")] |
|
|
|
#[post("/_matrix/client/r0/rooms/<_room_id>/join", data = "<body>")] |
|
|
|
@ -1220,6 +1335,7 @@ pub fn join_room_by_id_route( |
|
|
|
serde_json::to_value(event).unwrap(), |
|
|
|
serde_json::to_value(event).unwrap(), |
|
|
|
None, |
|
|
|
None, |
|
|
|
Some(user_id.to_string()), |
|
|
|
Some(user_id.to_string()), |
|
|
|
|
|
|
|
None, |
|
|
|
&db.globals, |
|
|
|
&db.globals, |
|
|
|
) |
|
|
|
) |
|
|
|
.unwrap(); |
|
|
|
.unwrap(); |
|
|
|
@ -1237,17 +1353,21 @@ pub fn join_room_by_id_or_alias_route( |
|
|
|
) -> MatrixResult<join_room_by_id_or_alias::Response> { |
|
|
|
) -> MatrixResult<join_room_by_id_or_alias::Response> { |
|
|
|
let room_id = match RoomId::try_from(body.room_id_or_alias.clone()) { |
|
|
|
let room_id = match RoomId::try_from(body.room_id_or_alias.clone()) { |
|
|
|
Ok(room_id) => room_id, |
|
|
|
Ok(room_id) => room_id, |
|
|
|
Err(room_alias) => { |
|
|
|
Err(_) => { |
|
|
|
if room_alias.server_name() == db.globals.server_name() { |
|
|
|
if let Some(room_id) = db |
|
|
|
|
|
|
|
.rooms |
|
|
|
|
|
|
|
.id_from_alias(&body.room_id_or_alias.clone().try_into().unwrap()) |
|
|
|
|
|
|
|
.unwrap() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
room_id |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
// Ask creator server of the room to join TODO ask someone else when not available
|
|
|
|
|
|
|
|
//server_server::send_request(data, destination, request)
|
|
|
|
return MatrixResult(Err(Error { |
|
|
|
return MatrixResult(Err(Error { |
|
|
|
kind: ErrorKind::NotFound, |
|
|
|
kind: ErrorKind::NotFound, |
|
|
|
message: "Room alias not found.".to_owned(), |
|
|
|
message: "Room alias not found.".to_owned(), |
|
|
|
status_code: http::StatusCode::BAD_REQUEST, |
|
|
|
status_code: http::StatusCode::BAD_REQUEST, |
|
|
|
})); |
|
|
|
})); |
|
|
|
} else { |
|
|
|
|
|
|
|
// Ask creator server of the room to join TODO ask someone else when not available
|
|
|
|
|
|
|
|
//server_server::send_request(data, destination, request)
|
|
|
|
|
|
|
|
todo!(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
@ -1285,6 +1405,7 @@ pub fn leave_room_route( |
|
|
|
json!({"membership": "leave"}), |
|
|
|
json!({"membership": "leave"}), |
|
|
|
None, |
|
|
|
None, |
|
|
|
Some(user_id.to_string()), |
|
|
|
Some(user_id.to_string()), |
|
|
|
|
|
|
|
None, |
|
|
|
&db.globals, |
|
|
|
&db.globals, |
|
|
|
) |
|
|
|
) |
|
|
|
.unwrap(); |
|
|
|
.unwrap(); |
|
|
|
@ -1328,6 +1449,7 @@ pub fn invite_user_route( |
|
|
|
serde_json::to_value(event).unwrap(), |
|
|
|
serde_json::to_value(event).unwrap(), |
|
|
|
None, |
|
|
|
None, |
|
|
|
Some(user_id.to_string()), |
|
|
|
Some(user_id.to_string()), |
|
|
|
|
|
|
|
None, |
|
|
|
&db.globals, |
|
|
|
&db.globals, |
|
|
|
) |
|
|
|
) |
|
|
|
.unwrap(); |
|
|
|
.unwrap(); |
|
|
|
@ -1342,6 +1464,35 @@ pub fn invite_user_route( |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[put("/_matrix/client/r0/directory/list/room/<_room_id>", data = "<body>")] |
|
|
|
|
|
|
|
pub async fn set_room_visibility_route( |
|
|
|
|
|
|
|
db: State<'_, Database>, |
|
|
|
|
|
|
|
body: Ruma<set_room_visibility::Request>, |
|
|
|
|
|
|
|
_room_id: String, |
|
|
|
|
|
|
|
) -> MatrixResult<set_room_visibility::Response> { |
|
|
|
|
|
|
|
match body.visibility { |
|
|
|
|
|
|
|
room::Visibility::Public => db.rooms.set_public(&body.room_id, true).unwrap(), |
|
|
|
|
|
|
|
room::Visibility::Private => db.rooms.set_public(&body.room_id, false).unwrap(), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MatrixResult(Ok(set_room_visibility::Response)) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[get("/_matrix/client/r0/directory/list/room/<_room_id>", data = "<body>")] |
|
|
|
|
|
|
|
pub async fn get_room_visibility_route( |
|
|
|
|
|
|
|
db: State<'_, Database>, |
|
|
|
|
|
|
|
body: Ruma<get_room_visibility::Request>, |
|
|
|
|
|
|
|
_room_id: String, |
|
|
|
|
|
|
|
) -> MatrixResult<get_room_visibility::Response> { |
|
|
|
|
|
|
|
MatrixResult(Ok(get_room_visibility::Response { |
|
|
|
|
|
|
|
visibility: if db.rooms.is_public_room(&body.room_id).unwrap() { |
|
|
|
|
|
|
|
room::Visibility::Public |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
room::Visibility::Private |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
})) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[get("/_matrix/client/r0/publicRooms", data = "<body>")] |
|
|
|
#[get("/_matrix/client/r0/publicRooms", data = "<body>")] |
|
|
|
pub async fn get_public_rooms_route( |
|
|
|
pub async fn get_public_rooms_route( |
|
|
|
db: State<'_, Database>, |
|
|
|
db: State<'_, Database>, |
|
|
|
@ -1399,9 +1550,10 @@ pub async fn get_public_rooms_filtered_route( |
|
|
|
) -> MatrixResult<get_public_rooms_filtered::Response> { |
|
|
|
) -> MatrixResult<get_public_rooms_filtered::Response> { |
|
|
|
let mut chunk = db |
|
|
|
let mut chunk = db |
|
|
|
.rooms |
|
|
|
.rooms |
|
|
|
.all_rooms() |
|
|
|
.public_rooms() |
|
|
|
.into_iter() |
|
|
|
|
|
|
|
.map(|room_id| { |
|
|
|
.map(|room_id| { |
|
|
|
|
|
|
|
let room_id = room_id.unwrap(); |
|
|
|
|
|
|
|
|
|
|
|
let state = db.rooms.room_state(&room_id).unwrap(); |
|
|
|
let state = db.rooms.room_state(&room_id).unwrap(); |
|
|
|
|
|
|
|
|
|
|
|
directory::PublicRoomsChunk { |
|
|
|
directory::PublicRoomsChunk { |
|
|
|
@ -1414,7 +1566,7 @@ pub async fn get_public_rooms_filtered_route( |
|
|
|
.deserialize() |
|
|
|
.deserialize() |
|
|
|
.unwrap() |
|
|
|
.unwrap() |
|
|
|
.alias |
|
|
|
.alias |
|
|
|
}).map(|a| a.to_string()), |
|
|
|
}), |
|
|
|
name: state.get(&(EventType::RoomName, "".to_owned())).map(|s| { |
|
|
|
name: state.get(&(EventType::RoomName, "".to_owned())).map(|s| { |
|
|
|
serde_json::from_value::<EventJson<ruma_events::room::name::NameEventContent>>( |
|
|
|
serde_json::from_value::<EventJson<ruma_events::room::name::NameEventContent>>( |
|
|
|
s.content.clone(), |
|
|
|
s.content.clone(), |
|
|
|
@ -1565,6 +1717,7 @@ pub fn create_message_event_route( |
|
|
|
serde_json::from_str(body.json_body.unwrap().get()).unwrap(), |
|
|
|
serde_json::from_str(body.json_body.unwrap().get()).unwrap(), |
|
|
|
Some(unsigned), |
|
|
|
Some(unsigned), |
|
|
|
None, |
|
|
|
None, |
|
|
|
|
|
|
|
None, |
|
|
|
&db.globals, |
|
|
|
&db.globals, |
|
|
|
) { |
|
|
|
) { |
|
|
|
MatrixResult(Ok(create_message_event::Response { event_id })) |
|
|
|
MatrixResult(Ok(create_message_event::Response { event_id })) |
|
|
|
@ -1590,14 +1743,49 @@ pub fn create_state_event_for_key_route( |
|
|
|
) -> MatrixResult<create_state_event_for_key::Response> { |
|
|
|
) -> MatrixResult<create_state_event_for_key::Response> { |
|
|
|
let user_id = body.user_id.as_ref().expect("user is authenticated"); |
|
|
|
let user_id = body.user_id.as_ref().expect("user is authenticated"); |
|
|
|
|
|
|
|
|
|
|
|
// Reponse of with/without key is the same
|
|
|
|
let content = |
|
|
|
|
|
|
|
serde_json::from_str::<serde_json::Value>(body.json_body.clone().unwrap().get()).unwrap(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if body.event_type == EventType::RoomCanonicalAlias { |
|
|
|
|
|
|
|
let canonical_alias = serde_json::from_value::< |
|
|
|
|
|
|
|
EventJson<canonical_alias::CanonicalAliasEventContent>, |
|
|
|
|
|
|
|
>(content.clone()) |
|
|
|
|
|
|
|
.unwrap() |
|
|
|
|
|
|
|
.deserialize() |
|
|
|
|
|
|
|
.unwrap(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut aliases = canonical_alias.alt_aliases; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if let Some(alias) = canonical_alias.alias { |
|
|
|
|
|
|
|
aliases.push(alias); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for alias in aliases { |
|
|
|
|
|
|
|
if alias.server_name() != db.globals.server_name() |
|
|
|
|
|
|
|
|| db |
|
|
|
|
|
|
|
.rooms |
|
|
|
|
|
|
|
.id_from_alias(&alias) |
|
|
|
|
|
|
|
.unwrap() |
|
|
|
|
|
|
|
.filter(|room| room == &body.room_id) // Make sure it's the right room
|
|
|
|
|
|
|
|
.is_none() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return MatrixResult(Err(Error { |
|
|
|
|
|
|
|
kind: ErrorKind::Unknown, |
|
|
|
|
|
|
|
message: "You are only allowed to send canonical_alias events when it's aliases already exists".to_owned(), |
|
|
|
|
|
|
|
status_code: http::StatusCode::BAD_REQUEST, |
|
|
|
|
|
|
|
})); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if let Ok(event_id) = db.rooms.append_pdu( |
|
|
|
if let Ok(event_id) = db.rooms.append_pdu( |
|
|
|
body.room_id.clone(), |
|
|
|
body.room_id.clone(), |
|
|
|
user_id.clone(), |
|
|
|
user_id.clone(), |
|
|
|
body.event_type.clone(), |
|
|
|
body.event_type.clone(), |
|
|
|
serde_json::from_str(body.json_body.clone().unwrap().get()).unwrap(), |
|
|
|
content, |
|
|
|
None, |
|
|
|
None, |
|
|
|
Some(body.state_key.clone()), |
|
|
|
Some(body.state_key.clone()), |
|
|
|
|
|
|
|
None, |
|
|
|
&db.globals, |
|
|
|
&db.globals, |
|
|
|
) { |
|
|
|
) { |
|
|
|
MatrixResult(Ok(create_state_event_for_key::Response { event_id })) |
|
|
|
MatrixResult(Ok(create_state_event_for_key::Response { event_id })) |
|
|
|
@ -1620,26 +1808,43 @@ pub fn create_state_event_for_empty_key_route( |
|
|
|
_room_id: String, |
|
|
|
_room_id: String, |
|
|
|
_event_type: String, |
|
|
|
_event_type: String, |
|
|
|
) -> MatrixResult<create_state_event_for_empty_key::Response> { |
|
|
|
) -> MatrixResult<create_state_event_for_empty_key::Response> { |
|
|
|
let user_id = body.user_id.as_ref().expect("user is authenticated"); |
|
|
|
// This just calls create_state_event_for_key_route
|
|
|
|
|
|
|
|
let Ruma { |
|
|
|
|
|
|
|
body: |
|
|
|
|
|
|
|
create_state_event_for_empty_key::Request { |
|
|
|
|
|
|
|
room_id, |
|
|
|
|
|
|
|
event_type, |
|
|
|
|
|
|
|
data, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
user_id, |
|
|
|
|
|
|
|
device_id, |
|
|
|
|
|
|
|
json_body, |
|
|
|
|
|
|
|
} = body; |
|
|
|
|
|
|
|
|
|
|
|
// Reponse of with/without key is the same
|
|
|
|
let response = create_state_event_for_key_route( |
|
|
|
if let Ok(event_id) = db.rooms.append_pdu( |
|
|
|
db, |
|
|
|
body.room_id.clone(), |
|
|
|
Ruma { |
|
|
|
user_id.clone(), |
|
|
|
body: create_state_event_for_key::Request { |
|
|
|
body.event_type.clone(), |
|
|
|
room_id, |
|
|
|
serde_json::from_str(body.json_body.unwrap().get()).unwrap(), |
|
|
|
event_type, |
|
|
|
None, |
|
|
|
data, |
|
|
|
Some("".to_owned()), |
|
|
|
state_key: "".to_owned(), |
|
|
|
&db.globals, |
|
|
|
}, |
|
|
|
) { |
|
|
|
user_id, |
|
|
|
MatrixResult(Ok(create_state_event_for_empty_key::Response { event_id })) |
|
|
|
device_id, |
|
|
|
} else { |
|
|
|
json_body, |
|
|
|
MatrixResult(Err(Error { |
|
|
|
}, |
|
|
|
kind: ErrorKind::Unknown, |
|
|
|
_room_id, |
|
|
|
message: "Failed to send event.".to_owned(), |
|
|
|
_event_type, |
|
|
|
status_code: http::StatusCode::BAD_REQUEST, |
|
|
|
"".to_owned(), |
|
|
|
})) |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MatrixResult(match response.0 { |
|
|
|
|
|
|
|
Ok(create_state_event_for_key::Response { event_id }) => { |
|
|
|
|
|
|
|
Ok(create_state_event_for_empty_key::Response { event_id }) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Err(e) => Err(e), |
|
|
|
|
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[get("/_matrix/client/r0/rooms/<_room_id>/state", data = "<body>")] |
|
|
|
#[get("/_matrix/client/r0/rooms/<_room_id>/state", data = "<body>")] |
|
|
|
@ -1933,17 +2138,19 @@ pub fn sync_route( |
|
|
|
let mut invited_rooms = BTreeMap::new(); |
|
|
|
let mut invited_rooms = BTreeMap::new(); |
|
|
|
for room_id in db.rooms.rooms_invited(&user_id) { |
|
|
|
for room_id in db.rooms.rooms_invited(&user_id) { |
|
|
|
let room_id = room_id.unwrap(); |
|
|
|
let room_id = room_id.unwrap(); |
|
|
|
let events = db |
|
|
|
|
|
|
|
.rooms |
|
|
|
|
|
|
|
.pdus_since(&room_id, since) |
|
|
|
|
|
|
|
.unwrap() |
|
|
|
|
|
|
|
.map(|pdu| pdu.unwrap().to_stripped_state_event()) |
|
|
|
|
|
|
|
.collect(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
invited_rooms.insert( |
|
|
|
invited_rooms.insert( |
|
|
|
room_id, |
|
|
|
room_id.clone(), |
|
|
|
sync_events::InvitedRoom { |
|
|
|
sync_events::InvitedRoom { |
|
|
|
invite_state: sync_events::InviteState { events }, |
|
|
|
invite_state: sync_events::InviteState { |
|
|
|
|
|
|
|
events: db |
|
|
|
|
|
|
|
.rooms |
|
|
|
|
|
|
|
.room_state(&room_id) |
|
|
|
|
|
|
|
.unwrap() |
|
|
|
|
|
|
|
.into_iter() |
|
|
|
|
|
|
|
.map(|(_, pdu)| pdu.to_stripped_state_event()) |
|
|
|
|
|
|
|
.collect(), |
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
}, |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -2046,12 +2253,12 @@ pub fn get_message_events_route( |
|
|
|
.map(|pdu| pdu.to_room_event()) |
|
|
|
.map(|pdu| pdu.to_room_event()) |
|
|
|
.collect::<Vec<_>>(); |
|
|
|
.collect::<Vec<_>>(); |
|
|
|
|
|
|
|
|
|
|
|
MatrixResult(Ok(get_message_events::Response { |
|
|
|
MatrixResult(Ok(dbg!(get_message_events::Response { |
|
|
|
start: Some(body.from.clone()), |
|
|
|
start: Some(body.from.clone()), |
|
|
|
end: prev_batch, |
|
|
|
end: prev_batch, |
|
|
|
chunk: room_events, |
|
|
|
chunk: room_events, |
|
|
|
state: Vec::new(), |
|
|
|
state: Vec::new(), |
|
|
|
})) |
|
|
|
}))) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
MatrixResult(Err(Error { |
|
|
|
MatrixResult(Err(Error { |
|
|
|
kind: ErrorKind::Unknown, |
|
|
|
kind: ErrorKind::Unknown, |
|
|
|
|