Implement encryption_enabled_by_default_for_room_type. (closes #29)

Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
Jason Volk
2025-11-01 22:44:36 +00:00
parent 8b1de3d8db
commit a14556da97
3 changed files with 57 additions and 1 deletions

View File

@@ -3,7 +3,8 @@ use std::collections::BTreeMap;
use axum::extract::State;
use futures::{FutureExt, future::OptionFuture};
use ruma::{
CanonicalJsonObject, Int, OwnedRoomAliasId, OwnedRoomId, OwnedUserId, RoomId, RoomVersionId,
CanonicalJsonObject, EventEncryptionAlgorithm, Int, OwnedRoomAliasId, OwnedRoomId,
OwnedUserId, RoomId, RoomVersionId,
api::client::room::{
self, create_room,
create_room::v3::{CreationContent, RoomPreset},
@@ -13,6 +14,7 @@ use ruma::{
room::{
canonical_alias::RoomCanonicalAliasEventContent,
create::RoomCreateEventContent,
encryption::RoomEncryptionEventContent,
guest_access::{GuestAccess, RoomGuestAccessEventContent},
history_visibility::{HistoryVisibility, RoomHistoryVisibilityEventContent},
join_rules::{JoinRule, RoomJoinRulesEventContent},
@@ -262,6 +264,7 @@ pub(crate) async fn create_room_route(
.await?;
// 6. Events listed in initial_state
let mut is_encrypted = false;
for event in &body.initial_state {
let mut pdu_builder = event
.deserialize_as_unchecked::<PduBuilder>()
@@ -292,6 +295,10 @@ pub(crate) async fn create_room_route(
continue;
}
if pdu_builder.event_type == TimelineEventType::RoomEncryption {
is_encrypted = true;
}
services
.timeline
.build_and_append_pdu(pdu_builder, sender_user, &room_id, &state_lock)
@@ -299,6 +306,33 @@ pub(crate) async fn create_room_route(
.await?;
}
if services.config.allow_encryption && !is_encrypted {
use RoomPreset::*;
let config = services
.config
.encryption_enabled_by_default_for_room_type
.as_deref()
.unwrap_or("off");
let invite = matches!(config, "invite");
let always = matches!(config, "all" | "invite");
if always || (invite && matches!(preset, PrivateChat | TrustedPrivateChat)) {
let algorithm = EventEncryptionAlgorithm::MegolmV1AesSha2;
let content = RoomEncryptionEventContent::new(algorithm);
services
.timeline
.build_and_append_pdu(
PduBuilder::state(String::new(), &content),
sender_user,
&room_id,
&state_lock,
)
.boxed()
.await?;
}
}
// 7. Events implied by name and topic
if let Some(name) = &body.name {
services

View File

@@ -590,6 +590,17 @@ pub struct Config {
#[serde(default = "true_fn")]
pub allow_encryption: bool,
/// Controls whether locally-created rooms should be end-to-end encrypted by
/// default. This option is equivalent to the one found in Synapse.
///
/// Options:
/// - "all": All created rooms are encrypted.
/// - "invite": Any room created with `private_chat` or
/// `trusted_private_chat` presets.
/// - Other values default to no effect.
#[serde(default)]
pub encryption_enabled_by_default_for_room_type: Option<String>,
/// Controls whether federation is allowed or not. It is not recommended to
/// disable this after installation due to potential federation breakage but
/// this is technically not a permanent setting.

View File

@@ -459,6 +459,17 @@
#
#allow_encryption = true
# Controls whether locally-created rooms should be end-to-end encrypted by
# default. This option is equivalent to the one found in Synapse.
#
# Options:
# - "all": All created rooms are encrypted.
# - "invite": Any room created with `private_chat` or
# `trusted_private_chat` presets.
# - Other values default to no effect.
#
#encryption_enabled_by_default_for_room_type = false
# Controls whether federation is allowed or not. It is not recommended to
# disable this after installation due to potential federation breakage but
# this is technically not a permanent setting.