From e923f63c4919a9eb65f074c8099fc7bc115925ee Mon Sep 17 00:00:00 2001
From: AndSDev <AndSDev@gmail.com>
Date: Fri, 14 Oct 2022 14:45:05 +0300
Subject: [PATCH] fix(service/rooms/timeline): fix validating for non-joined
 members

---
 src/service/rooms/timeline/mod.rs | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs
index 9494f67df..403b400d8 100644
--- a/src/service/rooms/timeline/mod.rs
+++ b/src/service/rooms/timeline/mod.rs
@@ -705,13 +705,17 @@ struct ExtractMembership {
                         membership: MembershipState,
                     }
 
+                    let target = pdu
+                        .state_key()
+                        .filter(|v| v.starts_with("@"))
+                        .unwrap_or(sender.as_str());
                     let server_name = services().globals.server_name();
+                    let server_user = format!("@conduit:{}", server_name);
                     let content = serde_json::from_str::<ExtractMembership>(pdu.content.get())
                         .map_err(|_| Error::bad_database("Invalid content in pdu."))?;
 
                     if content.membership == MembershipState::Leave {
-                        let server_user = format!("@conduit:{}", server_name);
-                        if sender == &server_user {
+                        if target == &server_user {
                             warn!("Conduit user cannot leave from admins room");
                             return Err(Error::BadRequest(
                                 ErrorKind::Forbidden,
@@ -725,8 +729,9 @@ struct ExtractMembership {
                             .room_members(room_id)
                             .filter_map(|m| m.ok())
                             .filter(|m| m.server_name() == server_name)
+                            .filter(|m| m != target)
                             .count();
-                        if count < 3 {
+                        if count < 2 {
                             warn!("Last admin cannot leave from admins room");
                             return Err(Error::BadRequest(
                                 ErrorKind::Forbidden,
@@ -736,8 +741,7 @@ struct ExtractMembership {
                     }
 
                     if content.membership == MembershipState::Ban && pdu.state_key().is_some() {
-                        let server_user = format!("@conduit:{}", server_name);
-                        if pdu.state_key().as_ref().unwrap() == &server_user {
+                        if target == &server_user {
                             warn!("Conduit user cannot be banned in admins room");
                             return Err(Error::BadRequest(
                                 ErrorKind::Forbidden,
@@ -751,8 +755,9 @@ struct ExtractMembership {
                             .room_members(room_id)
                             .filter_map(|m| m.ok())
                             .filter(|m| m.server_name() == server_name)
+                            .filter(|m| m != target)
                             .count();
-                        if count < 3 {
+                        if count < 2 {
                             warn!("Last admin cannot be banned in admins room");
                             return Err(Error::BadRequest(
                                 ErrorKind::Forbidden,
-- 
GitLab