feat: room visibility and aliases

merge-requests/22/head
timokoesters 4 years ago
parent 9c26e22ad7
commit 4e507ef706
No known key found for this signature in database
GPG Key ID: 356E705610F626D5

109
Cargo.lock generated

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

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

@ -37,7 +37,7 @@ Also check out the [milestones](https://git.koesters.xyz/timo/conduit/milestones
#### How can I contribute? #### 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 #### Donate

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

@ -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::{
@ -39,16 +43,16 @@ use ruma_client_api::{
to_device::{self, send_event_to_device}, to_device::{self, send_event_to_device},
typing::create_typing_event, typing::create_typing_event,
uiaa::{AuthFlow, UiaaInfo, UiaaResponse}, uiaa::{AuthFlow, UiaaInfo, UiaaResponse},
user_directory::search_users, redact::redact_event, user_directory::search_users,
}, },
unversioned::get_supported_versions, unversioned::get_supported_versions,
}; };
use ruma_events::{ use ruma_events::{
collections::only::Event as EduEvent, 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, 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};
@ -671,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,
})) }))
} }
@ -908,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(),
@ -917,11 +945,11 @@ 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
.as_ref() .as_ref()
.map_or(true, |c| c.federate), .and_then(|c| c.predecessor.clone()),
predecessor: body.creation_content.as_ref().and_then(|c| c.predecessor.clone()),
room_version: RoomVersionId::version_5(), room_version: RoomVersionId::version_5(),
}) })
.unwrap(), .unwrap(),
@ -932,7 +960,7 @@ pub fn create_room_route(
) )
.unwrap(); .unwrap();
// Join room // 2. Let the room creator join
db.rooms db.rooms
.append_pdu( .append_pdu(
room_id.clone(), room_id.clone(),
@ -960,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 {
@ -972,8 +1000,18 @@ pub fn create_room_route(
.expect("TODO: handle. we hope the client sends a valid power levels json") .expect("TODO: handle. we hope the client sends a valid power levels json")
} else { } else {
serde_json::to_value(ruma_events::room::power_levels::PowerLevelsEventContent { 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, users,
..Default::default() users_default: 0.into(),
notifications: ruma_events::room::power_levels::NotificationPowerLevels {
room: 50.into(),
},
}) })
.unwrap() .unwrap()
}; };
@ -990,8 +1028,8 @@ pub fn create_room_route(
) )
.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,7 +1054,7 @@ pub fn create_room_route(
) )
.unwrap(); .unwrap();
// 1.2 History Visibility // 4.2 History Visibility
db.rooms db.rooms
.append_pdu( .append_pdu(
room_id.clone(), room_id.clone(),
@ -1033,7 +1071,7 @@ pub fn create_room_route(
) )
.unwrap(); .unwrap();
// 1.3 Guest Access // 4.3 Guest Access
db.rooms db.rooms
.append_pdu( .append_pdu(
room_id.clone(), room_id.clone(),
@ -1058,7 +1096,7 @@ pub fn create_room_route(
) )
.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,
@ -1079,7 +1117,7 @@ pub fn create_room_route(
.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(
@ -1116,7 +1154,7 @@ pub fn create_room_route(
.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(
@ -1139,10 +1177,24 @@ pub fn create_room_route(
.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>")] #[put(
"/_matrix/client/r0/rooms/<_room_id>/redact/<_event_id>/<_txn_id>",
data = "<body>"
)]
pub fn redact_event_route( pub fn redact_event_route(
db: State<'_, Database>, db: State<'_, Database>,
body: Ruma<redact_event::Request>, body: Ruma<redact_event::Request>,
@ -1158,7 +1210,8 @@ pub fn redact_event_route(
EventType::RoomRedaction, EventType::RoomRedaction,
serde_json::to_value(redaction::RedactionEventContent { serde_json::to_value(redaction::RedactionEventContent {
reason: body.reason.clone(), reason: body.reason.clone(),
}).unwrap(), })
.unwrap(),
None, None,
None, None,
Some(body.event_id.clone()), 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>")] #[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()],
debug!("Room alias not found."); }))
return MatrixResult(Err(Error { } else {
kind: ErrorKind::NotFound, debug!("Room alias not found.");
message: "Room not found.".to_owned(), return MatrixResult(Err(Error {
status_code: http::StatusCode::BAD_REQUEST, kind: ErrorKind::NotFound,
})); message: "Room with alias not found.".to_owned(),
} 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>")]
@ -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()) { let room_id = match RoomId::try_from(body.room_id_or_alias.clone()) {
Ok(room_id) => room_id, Ok(room_id) => room_id,
Err(_) => { 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 room_id
} else { } else {
// Ask creator server of the room to join TODO ask someone else when not available // 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>")] #[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>,
@ -1436,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 {
@ -1628,12 +1743,46 @@ 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, None,
@ -1659,27 +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(),
None, },
&db.globals, user_id,
) { device_id,
MatrixResult(Ok(create_state_event_for_empty_key::Response { event_id })) json_body,
} else { },
MatrixResult(Err(Error { _room_id,
kind: ErrorKind::Unknown, _event_type,
message: "Failed to send event.".to_owned(), "".to_owned(),
status_code: http::StatusCode::BAD_REQUEST, );
}))
} 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>")]
@ -1973,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(),
},
}, },
); );
} }
@ -2086,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,

@ -77,6 +77,10 @@ impl Database {
roomid_pduleaves: db.open_tree("roomid_pduleaves").unwrap(), roomid_pduleaves: db.open_tree("roomid_pduleaves").unwrap(),
roomstateid_pdu: db.open_tree("roomstateid_pdu").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(), userroomid_joined: db.open_tree("userroomid_joined").unwrap(),
roomuserid_joined: db.open_tree("roomuserid_joined").unwrap(), roomuserid_joined: db.open_tree("roomuserid_joined").unwrap(),
userroomid_invited: db.open_tree("userroomid_invited").unwrap(), userroomid_invited: db.open_tree("userroomid_invited").unwrap(),

@ -11,7 +11,7 @@ use ruma_events::{
}, },
EventJson, EventType, EventJson, EventType,
}; };
use ruma_identifiers::{EventId, RoomId, UserId}; use ruma_identifiers::{EventId, RoomAliasId, RoomId, UserId};
use sled::IVec; use sled::IVec;
use std::{ use std::{
collections::{BTreeMap, HashMap}, collections::{BTreeMap, HashMap},
@ -27,6 +27,8 @@ pub struct Rooms {
pub(super) roomstateid_pdu: sled::Tree, // RoomStateId = Room + StateType + StateKey pub(super) roomstateid_pdu: sled::Tree, // RoomStateId = Room + StateType + StateKey
pub(super) alias_roomid: sled::Tree, 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) userroomid_joined: sled::Tree,
pub(super) roomuserid_joined: sled::Tree, pub(super) roomuserid_joined: sled::Tree,
@ -312,7 +314,7 @@ impl Rooms {
.join_rule .join_rule
}); });
if target_membership == member::MembershipState::Join { let authorized = if target_membership == member::MembershipState::Join {
let mut prev_events = prev_events.iter(); let mut prev_events = prev_events.iter();
let prev_event = self let prev_event = self
.get_pdu(prev_events.next().ok_or(Error::BadRequest( .get_pdu(prev_events.next().ok_or(Error::BadRequest(
@ -392,34 +394,30 @@ impl Rooms {
} }
} else { } else {
false false
};
if authorized {
// Update our membership info
self.update_membership(&room_id, &target_user_id, &target_membership)?;
} }
authorized
} }
EventType::RoomCreate => prev_events.is_empty(), 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 // TODO
sender_power.unwrap_or(&power_levels.users_default) sender_power.unwrap_or(&power_levels.users_default)
>= &power_levels.state_default >= &power_levels.state_default
} }
_ => false,
} { } {
error!("Unauthorized"); error!("Unauthorized");
// Not authorized // Not authorized
return Err(Error::BadRequest("event 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)? { } else if !self.is_joined(&sender, &room_id)? {
return Err(Error::BadRequest("event not authorized")); return Err(Error::BadRequest("event not authorized"));
@ -648,14 +646,66 @@ impl Rooms {
Ok(()) Ok(())
} }
pub fn id_from_alias(&self, alias: &str) -> Result<Option<RoomId>> { pub fn set_alias(
if !alias.starts_with('#') { &self,
return Err(Error::BadRequest("room alias does not start with #")); 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?)?;
}
}
}
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())?;
} }
self.alias_roomid.get(alias)?.map_or(Ok(None), |bytes| { Ok(())
Ok(Some(RoomId::try_from(utils::string_from_bytes(&bytes)?)?)) }
})
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. /// Returns an iterator over all rooms a user joined.

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

@ -50,12 +50,17 @@ fn setup_rocket() -> rocket::Rocket {
client_server::set_read_marker_route, client_server::set_read_marker_route,
client_server::create_typing_event_route, client_server::create_typing_event_route,
client_server::create_room_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::get_alias_route,
client_server::join_room_by_id_route, client_server::join_room_by_id_route,
client_server::join_room_by_id_or_alias_route, client_server::join_room_by_id_or_alias_route,
client_server::leave_room_route, client_server::leave_room_route,
client_server::forget_room_route, client_server::forget_room_route,
client_server::invite_user_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_route,
client_server::get_public_rooms_filtered_route, client_server::get_public_rooms_filtered_route,
client_server::search_users_route, client_server::search_users_route,

Loading…
Cancel
Save