Merge branch 'girlbossceo:main' into main

This commit is contained in:
sininenkissa 2024-02-29 09:38:27 +00:00 committed by GitHub
commit ba3446e4ec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 139 additions and 20 deletions

View file

@ -209,7 +209,7 @@ explicit_outlives_requirements = "warn"
# unreachable_pub = "warn"
unused_extern_crates = "warn"
unused_import_braces = "warn"
# unused_lifetimes = "warn"
unused_lifetimes = "warn"
unused_qualifications = "warn"
dead_code = "warn"

View file

@ -248,7 +248,7 @@ server {
location /_matrix/ {
# TCP
proxy_pass http://127.0.0.1:6167$request_uri;
proxy_pass http://127.0.0.1:6167;
# UNIX socket
#proxy_pass http://backend;

View file

@ -72,4 +72,5 @@
- Add admin command to bulk delete media via a codeblock list of MXC URLs.
- Add admin command to delete both the thumbnail and media MXC URLs from an event ID (e.g. from an abuse report)
- Add `!admin` as a way to call the Conduit admin bot
- Add support for listening on multiple TCP ports
- Add support for listening on multiple TCP ports
- Add admin command to list all the rooms a local user is joined in

View file

@ -70,7 +70,7 @@ docker run -d -p 8448:6167 \
or you can use [docker-compose](#docker-compose).
The `-d` flag lets the container run in detached mode. You now need to supply a `conduit.toml` config file, an example can be found [here](../conduit-example.toml).
The `-d` flag lets the container run in detached mode. You now need to supply a `conduit.toml` config file, an example can be found [here](../conduwuit-example.toml).
You can pass in different env vars to change config values on the fly. You can even configure Conduit completely by using env vars, but for that you need
to pass `-e CONDUIT_CONFIG=""` into your container. For an overview of possible values, please take a look at the `docker-compose.yml` file.
@ -131,7 +131,7 @@ So...step by step:
1. Copy [`docker-compose.for-traefik.yml`](docker-compose.for-traefik.yml) (or
[`docker-compose.with-traefik.yml`](docker-compose.with-traefik.yml)) and [`docker-compose.override.yml`](docker-compose.override.yml) from the repository and remove `.for-traefik` (or `.with-traefik`) from the filename.
2. Open both files and modify/adjust them to your needs. Meaning, change the `CONDUIT_SERVER_NAME` and the volume host mappings according to your needs.
3. Create the `conduit.toml` config file, an example can be found [here](../conduit-example.toml), or set `CONDUIT_CONFIG=""` and configure Conduit per env vars.
3. Create the `conduit.toml` config file, an example can be found [here](../conduwuit-example.toml), or set `CONDUIT_CONFIG=""` and configure Conduit per env vars.
4. Uncomment the `element-web` service if you want to host your own Element Web Client and create a `element_config.json`.
5. Create the files needed by the `well-known` service.

View file

@ -15,8 +15,8 @@ https://attic.kennel.juneis.dog/conduwuit
conduwuit:lYPVh7o1hLu1idH4Xt2QHaRa49WRGSAqzcfFd94aOTw=
```
You can now use the usual Nix commands to interact with Conduit's flake. For
example, `nix run gitlab:famedly/conduit` will run Conduit (though you'll need
You can now use the usual Nix commands to interact with conduwuit's flake. For
example, `nix run github:girlbossceo/conduwuit` will run conduwuit (though you'll need
to provide configuration and such manually as usual).
If your NixOS configuration is defined as a flake, you can depend on this flake
@ -25,7 +25,7 @@ add the following to your `inputs`:
```nix
conduit = {
url = "gitlab:famedly/conduit";
url = "github:girlbossceo/conduwuit";
# Assuming you have an input for nixpkgs called `nixpkgs`. If you experience
# build failures while using this, try commenting/deleting this line. This
@ -38,7 +38,7 @@ Next, make sure you're passing your flake inputs to the `specialArgs` argument
of `nixpkgs.lib.nixosSystem` [as explained here][specialargs]. This guide will
assume you've named the group `flake-inputs`.
Now you can configure Conduit and a reverse proxy for it. Add the following to
Now you can configure conduwuit and a reverse proxy for it. Add the following to
a new Nix file and include it in your configuration:
```nix
@ -144,7 +144,7 @@ in
];
locations."/_matrix/" = {
proxyPass = "http://backend_conduit$request_uri";
proxyPass = "http://backend_conduit";
proxyWebsockets = true;
extraConfig = ''
proxy_set_header Host $host;

View file

@ -1492,6 +1492,9 @@ pub async fn sync_events_v4_route(
let mut known_subscription_rooms = BTreeSet::new();
for (room_id, room) in &body.room_subscriptions {
if !services().rooms.metadata.exists(room_id)? {
continue;
}
let todo_room = todo_rooms
.entry(room_id.clone())
.or_insert((BTreeSet::new(), 0, u64::MAX));

View file

@ -1963,6 +1963,13 @@ pub async fn get_devices_route(
return Err(Error::bad_config("Federation is disabled."));
}
if body.user_id.server_name() != services().globals.server_name() {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"Tried to access user from other server.",
));
}
let sender_servername = body
.sender_servername
.as_ref()
@ -2044,7 +2051,7 @@ pub async fn get_profile_information_route(
if body.user_id.server_name() != services().globals.server_name() {
return Err(Error::BadRequest(
ErrorKind::NotFound,
ErrorKind::InvalidParam,
"User does not belong to this server",
));
}
@ -2085,6 +2092,17 @@ pub async fn get_keys_route(body: Ruma<get_keys::v1::Request>) -> Result<get_key
return Err(Error::bad_config("Federation is disabled."));
}
if body
.device_keys
.iter()
.any(|(u, _)| u.server_name() != services().globals.server_name())
{
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"User does not belong to this server.",
));
}
let result = get_keys_helper(
None,
&body.device_keys,
@ -2110,6 +2128,17 @@ pub async fn claim_keys_route(
return Err(Error::bad_config("Federation is disabled."));
}
if body
.one_time_keys
.iter()
.any(|(u, _)| u.server_name() != services().globals.server_name())
{
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"Tried to access user from other server.",
));
}
let result = claim_keys_helper(&body.one_time_keys).await?;
Ok(claim_keys::v1::Response {

View file

@ -190,7 +190,7 @@ impl KvTree for RocksDbEngineTree<'_> {
Ok(())
}
fn insert_batch<'a>(&self, iter: &mut dyn Iterator<Item = (Vec<u8>, Vec<u8>)>) -> Result<()> {
fn insert_batch(&self, iter: &mut dyn Iterator<Item = (Vec<u8>, Vec<u8>)>) -> Result<()> {
for (key, value) in iter {
self.db.rocks.put_cf(&self.cf(), key, value)?;
}
@ -247,7 +247,7 @@ impl KvTree for RocksDbEngineTree<'_> {
Ok(new)
}
fn increment_batch<'a>(&self, iter: &mut dyn Iterator<Item = Vec<u8>>) -> Result<()> {
fn increment_batch(&self, iter: &mut dyn Iterator<Item = Vec<u8>>) -> Result<()> {
let lock = self.write_lock.write().unwrap();
for key in iter {

View file

@ -5,7 +5,7 @@ use crate::{database::KeyValueDatabase, service, services, utils, Result};
type SearchPdusResult<'a> = Result<Option<(Box<dyn Iterator<Item = Vec<u8>> + 'a>, Vec<String>)>>;
impl service::rooms::search::Data for KeyValueDatabase {
fn index_pdu<'a>(&self, shortroomid: u64, pdu_id: &[u8], message_body: &str) -> Result<()> {
fn index_pdu(&self, shortroomid: u64, pdu_id: &[u8], message_body: &str) -> Result<()> {
let mut batch = message_body
.split_terminator(|c: char| !c.is_alphanumeric())
.filter(|s| !s.is_empty())

View file

@ -49,7 +49,7 @@ impl service::rooms::state::Data for KeyValueDatabase {
.collect()
}
fn set_forward_extremities<'a>(
fn set_forward_extremities(
&self,
room_id: &RoomId,
event_ids: Vec<OwnedEventId>,

View file

@ -330,7 +330,7 @@ fn count_to_id(
.rooms
.short
.get_shortroomid(room_id)?
.expect("room exists")
.ok_or_else(|| Error::bad_database("Looked for bad shortroomid in timeline"))?
.to_be_bytes()
.to_vec();
let mut pdu_id = prefix.clone();

View file

@ -179,6 +179,9 @@ enum UserCommand {
/// - List local users in the database
List,
/// - Lists all the rooms (local and remote) that the specified user is joined in
ListJoinedRooms { user_id: Box<UserId> },
}
#[cfg_attr(test, derive(Debug))]
@ -1005,6 +1008,52 @@ impl Service {
)
}
}
UserCommand::ListJoinedRooms { user_id } => {
if user_id.server_name() != services().globals.server_name() {
return Ok(RoomMessageEventContent::text_plain(
"User does not belong to our server.",
));
}
let mut rooms: Vec<(OwnedRoomId, u64, String)> = vec![]; // room ID, members joined, room name
for room_id in services().rooms.state_cache.rooms_joined(&user_id) {
let room_id = room_id?;
rooms.push(Self::get_room_info(room_id));
}
if rooms.is_empty() {
return Ok(RoomMessageEventContent::text_plain(
"User is not in any rooms.",
));
}
rooms.sort_by_key(|r| r.1);
rooms.reverse();
let output_plain = format!(
"Rooms {user_id} Joined:\n{}",
rooms
.iter()
.map(|(id, members, name)| format!(
"{id}\tMembers: {members}\tName: {name}"
))
.collect::<Vec<_>>()
.join("\n")
);
let output_html = format!(
"<table><caption>Rooms {user_id} Joined</caption>\n<tr><th>id</th>\t<th>members</th>\t<th>name</th></tr>\n{}</table>",
rooms
.iter()
.fold(String::new(), |mut output, (id, members, name)| {
writeln!(output, "<tr><td>{}</td>\t<td>{}</td>\t<td>{}</td></tr>", escape_html(id.as_ref()),
members,
escape_html(name)).unwrap();
output
})
);
RoomMessageEventContent::text_html(output_plain, output_html)
}
},
AdminCommand::Rooms(command) => match command {
RoomCommand::Moderation(command) => match command {

View file

@ -190,7 +190,22 @@ impl Service {
}
if errors >= 5 {
break;
// Timeout other events
match services()
.globals
.bad_event_ratelimiter
.write()
.unwrap()
.entry((*prev_id).to_owned())
{
hash_map::Entry::Vacant(e) => {
e.insert((Instant::now(), 1));
}
hash_map::Entry::Occupied(mut e) => {
*e.get_mut() = (Instant::now(), e.get().1 + 1)
}
}
continue;
}
if let Some((pdu, json)) = eventid_info.remove(&*prev_id) {

View file

@ -11,7 +11,7 @@ pub struct Service {
impl Service {
#[tracing::instrument(skip(self))]
pub fn index_pdu<'a>(&self, shortroomid: u64, pdu_id: &[u8], message_body: &str) -> Result<()> {
pub fn index_pdu(&self, shortroomid: u64, pdu_id: &[u8], message_body: &str) -> Result<()> {
self.db.index_pdu(shortroomid, pdu_id, message_body)
}

View file

@ -224,7 +224,7 @@ impl Service {
///
/// Returns pdu id
#[tracing::instrument(skip(self, pdu, pdu_json, leaves))]
pub async fn append_pdu<'a>(
pub async fn append_pdu(
&self,
pdu: &PduEvent,
mut pdu_json: CanonicalJsonObject,
@ -318,6 +318,28 @@ impl Service {
let mut pdu_id = shortroomid.to_be_bytes().to_vec();
pdu_id.extend_from_slice(&count2.to_be_bytes());
// https://spec.matrix.org/v1.9/rooms/v11/#moving-the-redacts-property-of-mroomredaction-events-to-a-content-property
// For backwards-compatibility with older clients,
// servers should add a redacts property to the top level of m.room.redaction events in when serving such events over the Client-Server API.
if pdu.kind == TimelineEventType::RoomRedaction
&& services().rooms.state.get_room_version(&pdu.room_id)? == RoomVersionId::V11
{
#[derive(Deserialize)]
struct Redaction {
redacts: Option<OwnedEventId>,
}
let content = serde_json::from_str::<Redaction>(pdu.content.get())
.map_err(|_| Error::bad_database("Invalid content in redaction pdu."))?;
if let Some(redact_id) = &content.redacts {
pdu_json.insert(
"redacts".to_owned(),
CanonicalJsonValue::String(redact_id.to_string()),
);
}
}
// Insert pdu
self.db.append_pdu(&pdu_id, pdu, &pdu_json, count2)?;
@ -1019,7 +1041,7 @@ impl Service {
/// Append the incoming event setting the state snapshot to the state from the
/// server that sent the event.
#[tracing::instrument(skip_all)]
pub async fn append_incoming_pdu<'a>(
pub async fn append_incoming_pdu(
&self,
pdu: &PduEvent,
pdu_json: CanonicalJsonObject,