option to control federating device display names

Signed-off-by: girlbossceo <june@girlboss.ceo>
This commit is contained in:
girlbossceo 2023-09-10 15:40:00 -04:00
parent 81e8df3102
commit 1b75d384d7
5 changed files with 47 additions and 10 deletions

View file

@ -64,3 +64,7 @@ allow_public_room_directory_over_federation = false
# Set this to true to allow your server's public room directory to be queried without client authentication (access token) through the Client APIs.
# Set this to false to protect against /publicRooms spiders.
allow_public_room_directory_without_auth = false
# Set this to true to allow federating device display names / allow external users to see your device display name.
# If federation is disabled entirely (`allow_federation`), this is inherently false.
allow_device_name_federation = false

View file

@ -72,8 +72,13 @@ pub async fn upload_keys_route(
pub async fn get_keys_route(body: Ruma<get_keys::v3::Request>) -> Result<get_keys::v3::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
let response =
get_keys_helper(Some(sender_user), &body.device_keys, |u| u == sender_user).await?;
let response = get_keys_helper(
Some(sender_user),
&body.device_keys,
|u| u == sender_user,
true, // Always allow local users to see device names of other local users
)
.await?;
Ok(response)
}
@ -259,6 +264,7 @@ pub(crate) async fn get_keys_helper<F: Fn(&UserId) -> bool>(
sender_user: Option<&UserId>,
device_keys_input: &BTreeMap<OwnedUserId, Vec<OwnedDeviceId>>,
allowed_signatures: F,
include_display_names: bool,
) -> Result<get_keys::v3::Response> {
let mut master_keys = BTreeMap::new();
let mut self_signing_keys = BTreeMap::new();
@ -290,8 +296,9 @@ pub(crate) async fn get_keys_helper<F: Fn(&UserId) -> bool>(
Error::bad_database("all_device_keys contained nonexistent device.")
})?;
add_unsigned_device_display_name(&mut keys, metadata)
add_unsigned_device_display_name(&mut keys, metadata, include_display_names)
.map_err(|_| Error::bad_database("invalid device keys in database"))?;
container.insert(device_id, keys);
}
}
@ -308,7 +315,7 @@ pub(crate) async fn get_keys_helper<F: Fn(&UserId) -> bool>(
"Tried to get keys for nonexistent device.",
))?;
add_unsigned_device_display_name(&mut keys, metadata)
add_unsigned_device_display_name(&mut keys, metadata, include_display_names)
.map_err(|_| Error::bad_database("invalid device keys in database"))?;
container.insert(device_id.to_owned(), keys);
}
@ -446,13 +453,21 @@ pub(crate) async fn get_keys_helper<F: Fn(&UserId) -> bool>(
fn add_unsigned_device_display_name(
keys: &mut Raw<ruma::encryption::DeviceKeys>,
metadata: ruma::api::client::device::Device,
include_display_names: bool,
) -> serde_json::Result<()> {
if let Some(display_name) = metadata.display_name {
let mut object = keys.deserialize_as::<serde_json::Map<String, serde_json::Value>>()?;
let unsigned = object.entry("unsigned").or_insert_with(|| json!({}));
if let serde_json::Value::Object(unsigned_object) = unsigned {
if include_display_names {
unsigned_object.insert("device_display_name".to_owned(), display_name.into());
} else {
unsigned_object.insert(
"device_display_name".to_owned(),
Some(metadata.device_id.as_str().to_string()).into(),
);
}
}
*keys = Raw::from_json(serde_json::value::to_raw_value(&object)?);

View file

@ -1848,13 +1848,18 @@ pub async fn get_devices_route(
.all_devices_metadata(&body.user_id)
.filter_map(|r| r.ok())
.filter_map(|metadata| {
let device_id_string = metadata.device_id.as_str().to_string();
let device_display_name = match services().globals.allow_device_name_federation() {
true => Some(device_id_string.to_string()),
false => metadata.display_name,
};
Some(UserDevice {
keys: services()
.users
.get_device_keys(&body.user_id, &metadata.device_id)
.ok()??,
device_id: metadata.device_id,
device_display_name: metadata.display_name,
device_display_name: device_display_name,
})
})
.collect(),
@ -1940,9 +1945,12 @@ pub async fn get_keys_route(body: Ruma<get_keys::v1::Request>) -> Result<get_key
return Err(Error::bad_config("Federation is disabled."));
}
let result = get_keys_helper(None, &body.device_keys, |u| {
Some(u.server_name()) == body.sender_servername.as_deref()
})
let result = get_keys_helper(
None,
&body.device_keys,
|u| Some(u.server_name()) == body.sender_servername.as_deref(),
services().globals.allow_device_name_federation(),
)
.await?;
Ok(get_keys::v1::Response {

View file

@ -55,6 +55,8 @@ pub struct Config {
pub allow_public_room_directory_over_federation: bool,
#[serde(default = "false_fn")]
pub allow_public_room_directory_without_auth: bool,
#[serde(default = "false_fn")]
pub allow_device_name_federation: bool,
#[serde(default = "true_fn")]
pub allow_room_creation: bool,
#[serde(default = "true_fn")]
@ -153,6 +155,10 @@ impl fmt::Display for Config {
),
("Allow encryption", &self.allow_encryption.to_string()),
("Allow federation", &self.allow_federation.to_string()),
(
"Allow device name federation",
&self.allow_device_name_federation.to_string(),
),
("Allow room creation", &self.allow_room_creation.to_string()),
(
"Allow public room directory over federation",

View file

@ -307,6 +307,10 @@ impl Service {
self.config.allow_public_room_directory_without_auth
}
pub fn allow_device_name_federation(&self) -> bool {
self.config.allow_device_name_federation
}
pub fn allow_room_creation(&self) -> bool {
self.config.allow_room_creation
}