feat: room visibility and aliases

next
timokoesters 2020-05-25 23:24:13 +02:00
parent 9c26e22ad7
commit 4e507ef706
No known key found for this signature in database
GPG Key ID: 356E705610F626D5
9 changed files with 399 additions and 158 deletions

109
Cargo.lock generated
View File

@ -32,7 +32,7 @@ checksum = "26c4f3195085c36ea8d24d32b2f828d23296a9370a28aa39d111f6f16bef9f3b"
dependencies = [
"proc-macro2 1.0.17",
"quote 1.0.6",
"syn 1.0.25",
"syn 1.0.29",
]
[[package]]
@ -279,7 +279,7 @@ dependencies = [
"bitflags",
"proc-macro2 1.0.17",
"quote 1.0.6",
"syn 1.0.25",
"syn 1.0.29",
]
[[package]]
@ -423,7 +423,7 @@ dependencies = [
"proc-macro-hack",
"proc-macro2 1.0.17",
"quote 1.0.6",
"syn 1.0.25",
"syn 1.0.29",
]
[[package]]
@ -557,9 +557,9 @@ checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
[[package]]
name = "hyper"
version = "0.13.5"
version = "0.13.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96816e1d921eca64d208a85aab4f7798455a8e34229ee5a88c935bdee1b78b14"
checksum = "a6e7655b9594024ad0ee439f3b5a7299369dc2a3f459b47c696f9ff676f9aa1f"
dependencies = [
"bytes",
"futures-channel",
@ -571,8 +571,8 @@ dependencies = [
"httparse",
"itoa",
"log",
"net2",
"pin-project",
"socket2",
"time",
"tokio",
"tower-service",
@ -663,9 +663,9 @@ dependencies = [
[[package]]
name = "js-sys"
version = "0.3.39"
version = "0.3.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa5a448de267e7358beaf4a5d849518fe9a0c13fce7afd44b06e68550e5562a7"
checksum = "ce10c23ad2ea25ceca0093bd3192229da4c5b3c0f2de499c1ecac0d98d452177"
dependencies = [
"wasm-bindgen",
]
@ -697,9 +697,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.70"
version = "0.2.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f"
checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
[[package]]
name = "lock_api"
@ -1004,7 +1004,7 @@ checksum = "e58db2081ba5b4c93bd6be09c40fd36cb9193a8336c384f3b40012e531aa7e40"
dependencies = [
"proc-macro2 1.0.17",
"quote 1.0.6",
"syn 1.0.25",
"syn 1.0.29",
]
[[package]]
@ -1195,9 +1195,9 @@ dependencies = [
[[package]]
name = "ring"
version = "0.16.13"
version = "0.16.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "703516ae74571f24b465b4a1431e81e2ad51336cb0ded733a55a1aa3eccac196"
checksum = "06b3fefa4f12272808f809a0af618501fdaba41a58963c5fb72238ab0be09603"
dependencies = [
"cc",
"libc",
@ -1291,13 +1291,13 @@ checksum = "52b82b4567b9af9b40a86f7778821c016ea961f55e4fee255f8f24bb28ee7452"
dependencies = [
"proc-macro2 1.0.17",
"quote 1.0.6",
"syn 1.0.25",
"syn 1.0.29",
]
[[package]]
name = "ruma-client-api"
version = "0.9.0"
source = "git+https://github.com/ruma/ruma-client-api.git#b064daf23dbf970933e83ce3b84a2563c5e646e7"
source = "git+https://github.com/ruma/ruma-client-api.git?rev=c725288cd099690c1d13f1a9b9e57228bc860a62#c725288cd099690c1d13f1a9b9e57228bc860a62"
dependencies = [
"http",
"js_int",
@ -1325,8 +1325,8 @@ dependencies = [
[[package]]
name = "ruma-events"
version = "0.21.2"
source = "git+https://github.com/ruma/ruma-events.git#a17714669da1db4aa7bf10948463bb964cf5058a"
version = "0.21.3"
source = "git+https://github.com/ruma/ruma-events.git?rev=4d09416cd1663d63c22153705c9e1fd77910797f#4d09416cd1663d63c22153705c9e1fd77910797f"
dependencies = [
"js_int",
"ruma-common",
@ -1335,16 +1335,17 @@ dependencies = [
"ruma-serde",
"serde",
"serde_json",
"strum",
]
[[package]]
name = "ruma-events-macros"
version = "0.21.2"
source = "git+https://github.com/ruma/ruma-events.git#a17714669da1db4aa7bf10948463bb964cf5058a"
version = "0.21.3"
source = "git+https://github.com/ruma/ruma-events.git?rev=4d09416cd1663d63c22153705c9e1fd77910797f#4d09416cd1663d63c22153705c9e1fd77910797f"
dependencies = [
"proc-macro2 1.0.17",
"quote 1.0.6",
"syn 1.0.25",
"syn 1.0.29",
]
[[package]]
@ -1491,22 +1492,22 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.110"
version = "1.0.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99e7b308464d16b56eba9964e4972a3eee817760ab60d88c3f86e1fecb08204c"
checksum = "c9124df5b40cbd380080b2cc6ab894c040a3070d995f5c9dc77e18c34a8ae37d"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.110"
version = "1.0.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "818fbf6bfa9a42d3bfcaca148547aa00c7b915bec71d1757aa2d44ca68771984"
checksum = "3f2c3ac8e6ca1e9c80b8be1023940162bf81ae3cffbb1809474152f2ce1eb250"
dependencies = [
"proc-macro2 1.0.17",
"quote 1.0.6",
"syn 1.0.25",
"syn 1.0.29",
]
[[package]]
@ -1570,6 +1571,18 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4"
[[package]]
name = "socket2"
version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"winapi 0.3.8",
]
[[package]]
name = "spin"
version = "0.5.2"
@ -1600,7 +1613,7 @@ dependencies = [
"heck",
"proc-macro2 1.0.17",
"quote 1.0.6",
"syn 1.0.25",
"syn 1.0.29",
]
[[package]]
@ -1616,9 +1629,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.25"
version = "1.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f14a640819f79b72a710c0be059dce779f9339ae046c8bef12c361d56702146f"
checksum = "bb37da98a55b1d08529362d9cbb863be17556873df2585904ab9d2bc951291d0"
dependencies = [
"proc-macro2 1.0.17",
"quote 1.0.6",
@ -1656,7 +1669,7 @@ checksum = "893582086c2f98cde18f906265a65b5030a074b1046c674ae898be6519a7f479"
dependencies = [
"proc-macro2 1.0.17",
"quote 1.0.6",
"syn 1.0.25",
"syn 1.0.29",
]
[[package]]
@ -1700,7 +1713,7 @@ checksum = "f0c3acc6aa564495a0f2e1d59fab677cd7f81a19994cfc7f3ad0e64301560389"
dependencies = [
"proc-macro2 1.0.17",
"quote 1.0.6",
"syn 1.0.25",
"syn 1.0.29",
]
[[package]]
@ -1858,9 +1871,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasm-bindgen"
version = "0.2.62"
version = "0.2.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c7d40d09cdbf0f4895ae58cf57d92e1e57a9dd8ed2e8390514b54a47cc5551"
checksum = "4c2dc4aa152834bc334f506c1a06b866416a8b6697d5c9f75b9a689c8486def0"
dependencies = [
"cfg-if",
"serde",
@ -1870,24 +1883,24 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.62"
version = "0.2.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3972e137ebf830900db522d6c8fd74d1900dcfc733462e9a12e942b00b4ac94"
checksum = "ded84f06e0ed21499f6184df0e0cb3494727b0c5da89534e0fcc55c51d812101"
dependencies = [
"bumpalo",
"lazy_static",
"log",
"proc-macro2 1.0.17",
"quote 1.0.6",
"syn 1.0.25",
"syn 1.0.29",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.12"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a369c5e1dfb7569e14d62af4da642a3cbc2f9a3652fe586e26ac22222aa4b04"
checksum = "64487204d863f109eb77e8462189d111f27cb5712cc9fdb3461297a76963a2f6"
dependencies = [
"cfg-if",
"js-sys",
@ -1897,9 +1910,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.62"
version = "0.2.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cd85aa2c579e8892442954685f0d801f9129de24fa2136b2c6a539c76b65776"
checksum = "838e423688dac18d73e31edce74ddfac468e37b1506ad163ffaf0a46f703ffe3"
dependencies = [
"quote 1.0.6",
"wasm-bindgen-macro-support",
@ -1907,28 +1920,28 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.62"
version = "0.2.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eb197bd3a47553334907ffd2f16507b4f4f01bbec3ac921a7719e0decdfe72a"
checksum = "3156052d8ec77142051a533cdd686cba889537b213f948cd1d20869926e68e92"
dependencies = [
"proc-macro2 1.0.17",
"quote 1.0.6",
"syn 1.0.25",
"syn 1.0.29",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.62"
version = "0.2.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a91c2916119c17a8e316507afaaa2dd94b47646048014bbdf6bef098c1bb58ad"
checksum = "c9ba19973a58daf4db6f352eda73dc0e289493cd29fb2632eb172085b6521acd"
[[package]]
name = "web-sys"
version = "0.3.39"
version = "0.3.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8bc359e5dd3b46cb9687a051d50a2fdd228e4ba7cf6fcf861a5365c3d671a642"
checksum = "7b72fe77fd39e4bd3eaa4412fd299a0be6b3dfe9d2597e2f1c20beb968f41d17"
dependencies = [
"js-sys",
"wasm-bindgen",
@ -1936,9 +1949,9 @@ dependencies = [
[[package]]
name = "webpki"
version = "0.21.2"
version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1f50e1972865d6b1adb54167d1c8ed48606004c2c9d0ea5f1eeb34d95e863ef"
checksum = "ab146130f5f790d45f82aeeb09e55a256573373ec64409fc19a6fb82fb1032ae"
dependencies = [
"ring",
"untrusted",

View File

@ -14,10 +14,10 @@ edition = "2018"
[dependencies]
rocket = { git = "https://github.com/SergioBenitez/Rocket.git", branch = "async", features = ["tls"] }
http = "0.2.1"
ruma-client-api = { git = "https://github.com/ruma/ruma-client-api.git" }
ruma-client-api = { git = "https://github.com/ruma/ruma-client-api.git", rev = "c725288cd099690c1d13f1a9b9e57228bc860a62" }
ruma-identifiers = { version = "0.16.1", features = ["rand"] }
ruma-api = "0.16.1"
ruma-events = { git = "https://github.com/ruma/ruma-events.git" }
ruma-events = { git = "https://github.com/ruma/ruma-events.git", rev = "4d09416cd1663d63c22153705c9e1fd77910797f" }
ruma-signatures = { git = "https://github.com/ruma/ruma-signatures.git", rev = "1ca545cba8dfd43e0fc8e3c18e1311fb73390a97" }
ruma-federation-api = { git = "https://github.com/ruma/ruma-federation-api.git", rev = "4cf4aa6ef74b25ad8c14d99d7774129f023df163" }
log = "0.4.8"
@ -25,15 +25,15 @@ sled = "0.31.0"
directories = "2.0.2"
js_int = "0.1.5"
serde_json = { version = "1.0.53", features = ["raw_value"] }
serde = "1.0.110"
serde = "1.0.111"
tokio = { version = "0.2.21", features = ["macros"] }
rand = "0.7.3"
rust-argon2 = "0.8.2"
reqwest = "0.10.4"
reqwest = "=0.10.4"
base64 = "0.12.1"
thiserror = "1.0.19"
ruma-common = "0.1.2"
image = { version = "0.23.4", default-features = false, features = ["jpeg", "png", "gif"] }
[patch.crates-io]
ruma-events = { git = "https://github.com/ruma/ruma-events.git" }
ruma-events = { git = "https://github.com/ruma/ruma-events.git", rev = "4d09416cd1663d63c22153705c9e1fd77910797f" }

View File

@ -37,7 +37,7 @@ Also check out the [milestones](https://git.koesters.xyz/timo/conduit/milestones
#### How can I contribute?
If you want to help, you may be able to find something in the issue tracker. If you do, comment on the issue, so others know. You can also join #conduit:matrix.org and ask there.
If you want to help, you may be able to find something in the issue tracker. If you do, comment on the issue, so others know. You can also join #conduit:matrix.org and ask there.
#### Donate

View File

@ -3,6 +3,9 @@ server_name = "your.server.name"
port = 8448
address = "0.0.0.0"
# Default path is in this user's data
#database_path = "/home/timo/MyConduitServer"
#[global.tls]
#certs = "/etc/letsencrypt/live/your.server.name/fullchain.pem"
#key = "/etc/letsencrypt/live/your.server.name/privkey.pem"

View File

@ -5,15 +5,18 @@ use std::{
};
use log::{debug, warn};
use rocket::{get, options, post, put, State};
use rocket::{delete, get, options, post, put, State};
use ruma_client_api::{
error::{Error, ErrorKind},
r0::{
account::{get_username_availability, register},
alias::get_alias,
alias::{create_alias, delete_alias, get_alias},
capabilities::get_capabilities,
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},
keys::{claim_keys, get_keys, upload_keys},
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},
read_marker::set_read_marker,
redact::redact_event,
room::{self, create_room},
session::{get_login_types, login, logout},
state::{
@ -39,16 +43,16 @@ use ruma_client_api::{
to_device::{self, send_event_to_device},
typing::create_typing_event,
uiaa::{AuthFlow, UiaaInfo, UiaaResponse},
user_directory::search_users, redact::redact_event,
user_directory::search_users,
},
unversioned::get_supported_versions,
};
use ruma_events::{
collections::only::Event as EduEvent,
room::{guest_access, history_visibility, join_rules, member, redaction},
room::{canonical_alias, guest_access, history_visibility, join_rules, member, redaction},
EventJson, EventType,
};
use ruma_identifiers::{RoomId, RoomVersionId, UserId};
use ruma_identifiers::{RoomAliasId, RoomId, RoomVersionId, UserId};
use serde_json::{json, value::RawValue};
use crate::{server_server, utils, Database, MatrixResult, Ruma};
@ -671,7 +675,7 @@ pub fn get_profile_route(
MatrixResult(Err(Error {
kind: ErrorKind::NotFound,
message: "Profile was not found.".to_owned(),
status_code: http::StatusCode::BAD_REQUEST,
status_code: http::StatusCode::NOT_FOUND,
}))
}
@ -908,8 +912,32 @@ pub fn create_room_route(
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");
// 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
.append_pdu(
room_id.clone(),
@ -917,11 +945,11 @@ pub fn create_room_route(
EventType::RoomCreate,
serde_json::to_value(ruma_events::room::create::CreateEventContent {
creator: user_id.clone(),
federate: body
federate: body.creation_content.as_ref().map_or(true, |c| c.federate),
predecessor: body
.creation_content
.as_ref()
.map_or(true, |c| c.federate),
predecessor: body.creation_content.as_ref().and_then(|c| c.predecessor.clone()),
.and_then(|c| c.predecessor.clone()),
room_version: RoomVersionId::version_5(),
})
.unwrap(),
@ -932,7 +960,7 @@ pub fn create_room_route(
)
.unwrap();
// Join room
// 2. Let the room creator join
db.rooms
.append_pdu(
room_id.clone(),
@ -960,7 +988,7 @@ pub fn create_room_route(
room::Visibility::Public => create_room::RoomPreset::PublicChat,
});
// 0. Power levels
// 3. Power levels
let mut users = BTreeMap::new();
users.insert(user_id.clone(), 100.into());
for invite_user_id in &body.invite {
@ -972,8 +1000,18 @@ pub fn create_room_route(
.expect("TODO: handle. we hope the client sends a valid power levels json")
} else {
serde_json::to_value(ruma_events::room::power_levels::PowerLevelsEventContent {
ban: 50.into(),
events: BTreeMap::new(),
events_default: 0.into(),
invite: 50.into(),
kick: 50.into(),
redact: 50.into(),
state_default: 50.into(),
users,
..Default::default()
users_default: 0.into(),
notifications: ruma_events::room::power_levels::NotificationPowerLevels {
room: 50.into(),
},
})
.unwrap()
};
@ -990,8 +1028,8 @@ pub fn create_room_route(
)
.unwrap();
// 1. Events set by preset
// 1.1 Join Rules
// 4. Events set by preset
// 4.1 Join Rules
db.rooms
.append_pdu(
room_id.clone(),
@ -1016,7 +1054,7 @@ pub fn create_room_route(
)
.unwrap();
// 1.2 History Visibility
// 4.2 History Visibility
db.rooms
.append_pdu(
room_id.clone(),
@ -1033,7 +1071,7 @@ pub fn create_room_route(
)
.unwrap();
// 1.3 Guest Access
// 4.3 Guest Access
db.rooms
.append_pdu(
room_id.clone(),
@ -1058,7 +1096,7 @@ pub fn create_room_route(
)
.unwrap();
// 2. Events listed in initial_state
// 5. Events listed in initial_state
for create_room::InitialStateEvent {
event_type,
state_key,
@ -1079,7 +1117,7 @@ pub fn create_room_route(
.unwrap();
}
// 3. Events implied by name and topic
// 6. Events implied by name and topic
if let Some(name) = &body.name {
db.rooms
.append_pdu(
@ -1116,7 +1154,7 @@ pub fn create_room_route(
.unwrap();
}
// 4. Events implied by invite (and TODO: invite_3pid)
// 7. Events implied by invite (and TODO: invite_3pid)
for user in &body.invite {
db.rooms
.append_pdu(
@ -1139,10 +1177,24 @@ pub fn create_room_route(
.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 }))
}
#[put("/_matrix/client/r0/rooms/<_room_id>/redact/<_event_id>/<_txn_id>", data = "<body>")]
#[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>,
@ -1158,7 +1210,8 @@ pub fn redact_event_route(
EventType::RoomRedaction,
serde_json::to_value(redaction::RedactionEventContent {
reason: body.reason.clone(),
}).unwrap(),
})
.unwrap(),
None,
None,
Some(body.event_id.clone()),
@ -1174,35 +1227,63 @@ pub fn redact_event_route(
}
}
#[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>")]
pub fn get_alias_route(
db: State<'_, Database>,
body: Ruma<get_alias::Request>,
_room_alias: String,
) -> MatrixResult<get_alias::Response> {
warn!("TODO: get_alias_route");
let room_id = if body.room_alias.server_name() == db.globals.server_name() {
match body.room_alias.alias() {
"conduit" => "!lgOCCXQKtXOAPlAlG5:conduit.rs",
_ => {
debug!("Room alias not found.");
return MatrixResult(Err(Error {
kind: ErrorKind::NotFound,
message: "Room not found.".to_owned(),
status_code: http::StatusCode::BAD_REQUEST,
}));
}
if body.room_alias.server_name() == db.globals.server_name() {
if let Some(room_id) = db.rooms.id_from_alias(&body.room_alias).unwrap() {
MatrixResult(Ok(get_alias::Response {
room_id,
servers: vec![db.globals.server_name().to_owned()],
}))
} else {
debug!("Room alias not found.");
return MatrixResult(Err(Error {
kind: ErrorKind::NotFound,
message: "Room with alias not found.".to_owned(),
status_code: http::StatusCode::BAD_REQUEST,
}));
}
} else {
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>")]
@ -1273,7 +1354,11 @@ pub fn join_room_by_id_or_alias_route(
let room_id = match RoomId::try_from(body.room_id_or_alias.clone()) {
Ok(room_id) => room_id,
Err(_) => {
if let Some(room_id) = db.rooms.id_from_alias(body.room_id_or_alias.as_ref()).unwrap() {
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
@ -1379,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>")]
pub async fn get_public_rooms_route(
db: State<'_, Database>,
@ -1436,9 +1550,10 @@ pub async fn get_public_rooms_filtered_route(
) -> MatrixResult<get_public_rooms_filtered::Response> {
let mut chunk = db
.rooms
.all_rooms()
.into_iter()
.public_rooms()
.map(|room_id| {
let room_id = room_id.unwrap();
let state = db.rooms.room_state(&room_id).unwrap();
directory::PublicRoomsChunk {
@ -1628,12 +1743,46 @@ pub fn create_state_event_for_key_route(
) -> MatrixResult<create_state_event_for_key::Response> {
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(
body.room_id.clone(),
user_id.clone(),
body.event_type.clone(),
serde_json::from_str(body.json_body.clone().unwrap().get()).unwrap(),
content,
None,
Some(body.state_key.clone()),
None,
@ -1659,27 +1808,43 @@ pub fn create_state_event_for_empty_key_route(
_room_id: String,
_event_type: String,
) -> 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
if let Ok(event_id) = db.rooms.append_pdu(
body.room_id.clone(),
user_id.clone(),
body.event_type.clone(),
serde_json::from_str(body.json_body.unwrap().get()).unwrap(),
None,
Some("".to_owned()),
None,
&db.globals,
) {
MatrixResult(Ok(create_state_event_for_empty_key::Response { event_id }))
} else {
MatrixResult(Err(Error {
kind: ErrorKind::Unknown,
message: "Failed to send event.".to_owned(),
status_code: http::StatusCode::BAD_REQUEST,
}))
}
let response = create_state_event_for_key_route(
db,
Ruma {
body: create_state_event_for_key::Request {
room_id,
event_type,
data,
state_key: "".to_owned(),
},
user_id,
device_id,
json_body,
},
_room_id,
_event_type,
"".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>")]
@ -1973,17 +2138,19 @@ pub fn sync_route(
let mut invited_rooms = BTreeMap::new();
for room_id in db.rooms.rooms_invited(&user_id) {
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(
room_id,
room_id.clone(),
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(),
},
},
);
}
@ -2086,12 +2253,12 @@ pub fn get_message_events_route(
.map(|pdu| pdu.to_room_event())
.collect::<Vec<_>>();
MatrixResult(Ok(get_message_events::Response {
MatrixResult(Ok(dbg!(get_message_events::Response {
start: Some(body.from.clone()),
end: prev_batch,
chunk: room_events,
state: Vec::new(),
}))
})))
} else {
MatrixResult(Err(Error {
kind: ErrorKind::Unknown,

View File

@ -77,6 +77,10 @@ impl Database {
roomid_pduleaves: db.open_tree("roomid_pduleaves").unwrap(),
roomstateid_pdu: db.open_tree("roomstateid_pdu").unwrap(),
alias_roomid: db.open_tree("alias_roomid").unwrap(),
aliasid_alias: db.open_tree("alias_roomid").unwrap(),
publicroomids: db.open_tree("publicroomids").unwrap(),
userroomid_joined: db.open_tree("userroomid_joined").unwrap(),
roomuserid_joined: db.open_tree("roomuserid_joined").unwrap(),
userroomid_invited: db.open_tree("userroomid_invited").unwrap(),

View File

@ -11,7 +11,7 @@ use ruma_events::{
},
EventJson, EventType,
};
use ruma_identifiers::{EventId, RoomId, UserId};
use ruma_identifiers::{EventId, RoomAliasId, RoomId, UserId};
use sled::IVec;
use std::{
collections::{BTreeMap, HashMap},
@ -27,6 +27,8 @@ pub struct Rooms {
pub(super) roomstateid_pdu: sled::Tree, // RoomStateId = Room + StateType + StateKey
pub(super) alias_roomid: sled::Tree,
pub(super) aliasid_alias: sled::Tree, // AliasId = RoomId + Count
pub(super) publicroomids: sled::Tree,
pub(super) userroomid_joined: sled::Tree,
pub(super) roomuserid_joined: sled::Tree,
@ -312,7 +314,7 @@ impl Rooms {
.join_rule
});
if target_membership == member::MembershipState::Join {
let authorized = if target_membership == member::MembershipState::Join {
let mut prev_events = prev_events.iter();
let prev_event = self
.get_pdu(prev_events.next().ok_or(Error::BadRequest(
@ -392,34 +394,30 @@ impl Rooms {
}
} else {
false
};
if authorized {
// Update our membership info
self.update_membership(&room_id, &target_user_id, &target_membership)?;
}
authorized
}
EventType::RoomCreate => prev_events.is_empty(),
_ if sender_membership == member::MembershipState::Join => {
// Not allow any of the following events if the sender is not joined.
_ if sender_membership != member::MembershipState::Join => false,
_ => {
// TODO
sender_power.unwrap_or(&power_levels.users_default)
>= &power_levels.state_default
}
_ => false,
} {
error!("Unauthorized");
// Not authorized
return Err(Error::BadRequest("event not authorized"));
}
if event_type == EventType::RoomMember {
// TODO: Don't get this twice
let target_user_id = UserId::try_from(&**state_key)?;
self.update_membership(
&room_id,
&target_user_id,
&serde_json::from_value::<EventJson<member::MemberEventContent>>(
content.clone(),
)?
.deserialize()?
.membership,
)?;
}
}
} else if !self.is_joined(&sender, &room_id)? {
return Err(Error::BadRequest("event not authorized"));
@ -648,14 +646,66 @@ impl Rooms {
Ok(())
}
pub fn id_from_alias(&self, alias: &str) -> Result<Option<RoomId>> {
if !alias.starts_with('#') {
return Err(Error::BadRequest("room alias does not start with #"));
pub fn set_alias(
&self,
alias: &RoomAliasId,
room_id: Option<&RoomId>,
globals: &super::globals::Globals,
) -> Result<()> {
if let Some(room_id) = room_id {
self.alias_roomid
.insert(alias.alias(), &*room_id.to_string())?;
let mut aliasid = room_id.to_string().as_bytes().to_vec();
aliasid.extend_from_slice(&globals.next_count()?.to_be_bytes());
self.aliasid_alias.insert(aliasid, &*alias.alias())?;
} else {
if let Some(room_id) = self.alias_roomid.remove(alias.alias())? {
for key in self.aliasid_alias.scan_prefix(room_id).keys() {
self.aliasid_alias.remove(key?)?;
}
}
}
self.alias_roomid.get(alias)?.map_or(Ok(None), |bytes| {
Ok(Some(RoomId::try_from(utils::string_from_bytes(&bytes)?)?))
})
Ok(())
}
pub fn id_from_alias(&self, alias: &RoomAliasId) -> Result<Option<RoomId>> {
self.alias_roomid
.get(alias.alias())?
.map_or(Ok(None), |bytes| {
Ok(Some(RoomId::try_from(utils::string_from_bytes(&bytes)?)?))
})
}
pub fn room_aliases(&self, room_id: &RoomId) -> impl Iterator<Item = Result<RoomAliasId>> {
let mut prefix = room_id.to_string().as_bytes().to_vec();
prefix.push(0xff);
self.aliasid_alias
.scan_prefix(prefix)
.values()
.map(|bytes| Ok(RoomAliasId::try_from(utils::string_from_bytes(&bytes?)?)?))
}
pub fn set_public(&self, room_id: &RoomId, public: bool) -> Result<()> {
if public {
self.publicroomids.insert(room_id.to_string(), &[])?;
} else {
self.publicroomids.remove(room_id.to_string())?;
}
Ok(())
}
pub fn is_public_room(&self, room_id: &RoomId) -> Result<bool> {
Ok(self.publicroomids.contains_key(room_id.to_string())?)
}
pub fn public_rooms(&self) -> impl Iterator<Item = Result<RoomId>> {
self.publicroomids
.iter()
.keys()
.map(|bytes| Ok(RoomId::try_from(utils::string_from_bytes(&bytes?)?)?))
}
/// Returns an iterator over all rooms a user joined.

View File

@ -141,9 +141,8 @@ impl Users {
let mut prefix = userdeviceid.clone();
prefix.push(0xff);
for result in self.todeviceid_events.scan_prefix(&prefix) {
let (key, value) = result?;
self.todeviceid_events.remove(key)?;
for key in self.todeviceid_events.scan_prefix(&prefix).keys() {
self.todeviceid_events.remove(key?)?;
}
// TODO: Remove onetimekeys

View File

@ -50,12 +50,17 @@ fn setup_rocket() -> rocket::Rocket {
client_server::set_read_marker_route,
client_server::create_typing_event_route,
client_server::create_room_route,
client_server::redact_event_route,
client_server::create_alias_route,
client_server::delete_alias_route,
client_server::get_alias_route,
client_server::join_room_by_id_route,
client_server::join_room_by_id_or_alias_route,
client_server::leave_room_route,
client_server::forget_room_route,
client_server::invite_user_route,
client_server::set_room_visibility_route,
client_server::get_room_visibility_route,
client_server::get_public_rooms_route,
client_server::get_public_rooms_filtered_route,
client_server::search_users_route,