matrix-mcp: auto-join only on accounts that live on the swarm homeserver
This commit is contained in:
parent
852d98e8dd
commit
513530ae35
1 changed files with 53 additions and 10 deletions
|
|
@ -130,7 +130,7 @@ pub async fn sweep_invites<S: BuildHasher>(
|
|||
// from the unread sweep's `<room>` key) so the two never collide; the
|
||||
// harness coalesces the wake iff the summary is new or changed, so
|
||||
// re-upserting an unchanged invite every tick is a cheap no-op.
|
||||
let own_server = client.user_id().map(|u| u.server_name().to_owned());
|
||||
let own_server = swarm_server(client);
|
||||
for room in ¤t {
|
||||
let room_id = room.room_id().to_owned();
|
||||
let inviter = room
|
||||
|
|
@ -139,8 +139,8 @@ pub async fn sweep_invites<S: BuildHasher>(
|
|||
.ok()
|
||||
.and_then(|d| d.inviter)
|
||||
.map(|m| m.user_id().to_owned());
|
||||
// An invite from the swarm's own homeserver is trusted: join it
|
||||
// without waking the agent. A failed join falls through to the todo
|
||||
// An invite from a user of the swarm's own homeserver, to an account
|
||||
// that lives on it, is trusted: join it without waking the agent. A failed join falls through to the todo
|
||||
// below, so the invite is never lost.
|
||||
if is_local(own_server.as_deref(), inviter.as_deref()) {
|
||||
match room.join().await {
|
||||
|
|
@ -179,8 +179,25 @@ pub async fn sweep_invites<S: BuildHasher>(
|
|||
}
|
||||
}
|
||||
|
||||
/// Whether `inviter` is a user of the agent's own homeserver. No known
|
||||
/// inviter or no known own server counts as external.
|
||||
/// The swarm homeserver's server name when `client` is an account on it, else
|
||||
/// `None`. The swarm homeserver is the daemon-wide `HIVE_MATRIX_URL`; a linked
|
||||
/// account on another server (matrix.org, catgirl.cloud, ...) is not on it, so
|
||||
/// its same-server inviters are strangers, not swarm members.
|
||||
fn swarm_server(client: &Client) -> Option<matrix_sdk::ruma::OwnedServerName> {
|
||||
let swarm = reqwest::Url::parse(&crate::paths::homeserver_url()?).ok()?;
|
||||
same_homeserver(&swarm, &client.homeserver())
|
||||
.then(|| client.user_id().map(|u| u.server_name().to_owned()))
|
||||
.flatten()
|
||||
}
|
||||
|
||||
/// Whether two homeserver URLs point at the same host and port.
|
||||
fn same_homeserver(a: &reqwest::Url, b: &reqwest::Url) -> bool {
|
||||
a.host_str() == b.host_str() && a.port_or_known_default() == b.port_or_known_default()
|
||||
}
|
||||
|
||||
/// Whether `inviter` is a user of the swarm homeserver `own` (the account's
|
||||
/// server when the account is on it, else `None`). No known inviter or no
|
||||
/// swarm server counts as external.
|
||||
fn is_local(own: Option<&ServerName>, inviter: Option<&UserId>) -> bool {
|
||||
matches!((own, inviter), (Some(own), Some(u)) if u.server_name() == own)
|
||||
}
|
||||
|
|
@ -197,7 +214,7 @@ pub(crate) fn invite_key(room_id: &matrix_sdk::ruma::RoomId) -> String {
|
|||
mod invite_tests {
|
||||
use matrix_sdk::ruma::{server_name, user_id};
|
||||
|
||||
use super::is_local;
|
||||
use super::{is_local, same_homeserver};
|
||||
|
||||
#[test]
|
||||
fn only_an_inviter_on_the_own_homeserver_is_local() {
|
||||
|
|
@ -216,4 +233,28 @@ mod invite_tests {
|
|||
assert!(!is_local(Some(own), None));
|
||||
assert!(!is_local(None, Some(user_id!("@mara:pr1ma.darkest.space"))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_account_is_on_the_swarm_homeserver_only_by_host_and_port() {
|
||||
let u = |s: &str| reqwest::Url::parse(s).expect("url");
|
||||
let swarm = u("https://matrix.pr1ma.darkest.space");
|
||||
assert!(same_homeserver(
|
||||
&swarm,
|
||||
&u("https://matrix.pr1ma.darkest.space/")
|
||||
));
|
||||
assert!(same_homeserver(
|
||||
&swarm,
|
||||
&u("https://matrix.pr1ma.darkest.space:443")
|
||||
));
|
||||
// A public server is a different host, and a different port is a
|
||||
// different server.
|
||||
assert!(!same_homeserver(&swarm, &u("https://catgirl.cloud")));
|
||||
assert!(!same_homeserver(
|
||||
&swarm,
|
||||
&u("https://matrix.pr1ma.darkest.space:8448")
|
||||
));
|
||||
// An external account gets no swarm server, so even its own
|
||||
// same-server inviter is not local.
|
||||
assert!(!is_local(None, Some(user_id!("@x:catgirl.cloud"))));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue