mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-11-15 05:06:53 +00:00
feat: Distinguish between ignore and block internally
This commit is contained in:
1 parent
00d369c441
commit
3c941734cd
10 files changed
+98
-35
No files matched your search
@@ -48,14 +48,13 @@ pub(crate) async fn invite_user_route(
|
||||
|
||||
match &body.recipient {
|
||||
| invite_user::v3::InvitationRecipient::UserId { user_id } => {
|
||||
let sender_ignored_recipient = services.users.user_is_ignored(sender_user, user_id);
|
||||
let recipient_ignored_by_sender =
|
||||
services.users.user_is_ignored(user_id, sender_user);
|
||||
let sender_filter_level = services.users.user_filter_level(sender_user, user_id);
|
||||
let recipient_filter_level = services.users.user_filter_level(user_id, sender_user);
|
||||
|
||||
let (sender_ignored_recipient, recipient_ignored_by_sender) =
|
||||
join!(sender_ignored_recipient, recipient_ignored_by_sender);
|
||||
let (sender_filter_level, recipient_filter_level) =
|
||||
join!(sender_filter_level, recipient_filter_level);
|
||||
|
||||
if sender_ignored_recipient {
|
||||
if !sender_filter_level.allowed() {
|
||||
return Ok(invite_user::v3::Response {});
|
||||
}
|
||||
|
||||
@@ -70,7 +69,7 @@ pub(crate) async fn invite_user_route(
|
||||
}
|
||||
}
|
||||
|
||||
if recipient_ignored_by_sender {
|
||||
if !recipient_filter_level.allowed() {
|
||||
// silently drop the invite to the recipient if they've been ignored by the
|
||||
// sender, pretend it worked
|
||||
return Ok(invite_user::v3::Response {});
|
||||
|
||||
@@ -286,11 +286,12 @@ where
|
||||
|
||||
if ignored_type
|
||||
&& (ignored_server
|
||||
|| (!services.config.send_messages_from_ignored_users_to_client
|
||||
&& services
|
||||
|| !(services.config.send_messages_from_ignored_users_to_client
|
||||
|| services
|
||||
.users
|
||||
.user_is_ignored(event.sender(), user_id)
|
||||
.await))
|
||||
.user_filter_level(event.sender(), user_id)
|
||||
.await
|
||||
.allowed()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -223,9 +223,20 @@ pub(crate) async fn create_room_route(
|
||||
|
||||
if preset == RoomPreset::TrustedPrivateChat {
|
||||
for invite in &body.invite {
|
||||
if services.users.user_is_ignored(sender_user, invite).await {
|
||||
if !services
|
||||
.users
|
||||
.user_filter_level(sender_user, invite)
|
||||
.await
|
||||
.allowed()
|
||||
{
|
||||
// don't send invites to users the sender has ignored
|
||||
continue;
|
||||
} else if services.users.user_is_ignored(invite, sender_user).await {
|
||||
} else if !services
|
||||
.users
|
||||
.user_filter_level(invite, sender_user)
|
||||
.await
|
||||
.allowed()
|
||||
{
|
||||
// silently drop the invite to the recipient if they've been ignored by the
|
||||
// sender, pretend it worked
|
||||
continue;
|
||||
@@ -400,9 +411,20 @@ pub(crate) async fn create_room_route(
|
||||
// 8. Events implied by invite (and TODO: invite_3pid)
|
||||
drop(state_lock);
|
||||
for user_id in &body.invite {
|
||||
if services.users.user_is_ignored(sender_user, user_id).await {
|
||||
if !services
|
||||
.users
|
||||
.user_filter_level(sender_user, user_id)
|
||||
.await
|
||||
.allowed()
|
||||
{
|
||||
// don't send invites to users the sender has ignored
|
||||
continue;
|
||||
} else if services.users.user_is_ignored(user_id, sender_user).await {
|
||||
} else if !services
|
||||
.users
|
||||
.user_filter_level(user_id, sender_user)
|
||||
.await
|
||||
.allowed()
|
||||
{
|
||||
// silently drop the invite to the recipient if they've been ignored by the
|
||||
// sender, pretend it worked
|
||||
continue;
|
||||
|
||||
@@ -624,9 +624,10 @@ async fn load_joined_room(
|
||||
.filter_map(|(read_user, _, edu)| async move {
|
||||
services
|
||||
.users
|
||||
.user_is_ignored(read_user, sender_user)
|
||||
.user_filter_level(read_user, sender_user)
|
||||
.await
|
||||
.or_some((read_user.to_owned(), edu))
|
||||
.allowed()
|
||||
.then_some((read_user.to_owned(), edu))
|
||||
})
|
||||
.collect::<HashMap<OwnedUserId, Raw<AnySyncEphemeralRoomEvent>>>()
|
||||
.map(Ok);
|
||||
|
||||
@@ -558,9 +558,10 @@ pub(crate) async fn sync_events_v4_route(
|
||||
.filter_map(|(read_user, _ts, v)| async move {
|
||||
services
|
||||
.users
|
||||
.user_is_ignored(read_user, sender_user)
|
||||
.user_filter_level(read_user, sender_user)
|
||||
.await
|
||||
.or_some(v)
|
||||
.allowed()
|
||||
.then_some(v)
|
||||
})
|
||||
.collect()
|
||||
.await;
|
||||
|
||||
@@ -455,9 +455,10 @@ where
|
||||
.filter_map(|(read_user, _ts, v)| async move {
|
||||
services
|
||||
.users
|
||||
.user_is_ignored(read_user, sender_user)
|
||||
.user_filter_level(read_user, sender_user)
|
||||
.await
|
||||
.or_some(v)
|
||||
.allowed()
|
||||
.then_some(v)
|
||||
})
|
||||
.collect()
|
||||
.await;
|
||||
|
||||
@@ -122,7 +122,13 @@ pub async fn update_membership(
|
||||
},
|
||||
| MembershipState::Invite => {
|
||||
// We want to know if the sender is ignored by the receiver
|
||||
if self.services.users.user_is_ignored(sender, user_id).await {
|
||||
if !self
|
||||
.services
|
||||
.users
|
||||
.user_filter_level(sender, user_id)
|
||||
.await
|
||||
.allowed()
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
||||
@@ -193,9 +193,9 @@ where
|
||||
.state_cache
|
||||
.active_local_users_in_room(pdu.room_id())
|
||||
.map(ToOwned::to_owned)
|
||||
// Don't notify the sender of their own events, and dont send from ignored users
|
||||
// Don't notify the sender of their own events, and don't send from ignored users
|
||||
.ready_filter(|user| *user != pdu.sender())
|
||||
.filter_map(|recipient_user| async move { (!self.services.users.user_is_ignored(pdu.sender(), &recipient_user).await).then_some(recipient_user) })
|
||||
.filter_map(|recipient_user| async move { (self.services.users.user_filter_level(pdu.sender(), &recipient_user).await.allowed()).then_some(recipient_user) })
|
||||
.collect()
|
||||
.await;
|
||||
|
||||
|
||||
@@ -12,7 +12,11 @@ use ruma::{
|
||||
};
|
||||
use tokio::sync::{RwLock, broadcast};
|
||||
|
||||
use crate::{Dep, globals, sending, sending::EduBuf, users};
|
||||
use crate::{
|
||||
Dep, globals,
|
||||
sending::{self, EduBuf},
|
||||
users::{self},
|
||||
};
|
||||
|
||||
pub struct Service {
|
||||
server: Arc<Server>,
|
||||
@@ -197,11 +201,11 @@ impl Service {
|
||||
.into_keys()
|
||||
.stream()
|
||||
.filter_map(|typing_user_id| async move {
|
||||
(!self
|
||||
.services
|
||||
self.services
|
||||
.users
|
||||
.user_is_ignored(&typing_user_id, sender_user)
|
||||
.await)
|
||||
.user_filter_level(&typing_user_id, sender_user)
|
||||
.await
|
||||
.allowed()
|
||||
.then_some(typing_user_id)
|
||||
})
|
||||
.collect()
|
||||
|
||||
@@ -39,6 +39,22 @@ pub struct UserSuspension {
|
||||
pub suspended_by: String,
|
||||
}
|
||||
|
||||
/// Represents a user's level of filtering on actions from another user.
|
||||
/// "Ignore" and "block" are defined in [MSC4283].
|
||||
/// This may be moved into Ruwuma in the future.
|
||||
///
|
||||
/// MSC4283: https://github.com/matrix-org/matrix-spec-proposals/pull/4283
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum UserFilterLevel {
|
||||
Allow,
|
||||
Ignore,
|
||||
Block,
|
||||
}
|
||||
|
||||
impl UserFilterLevel {
|
||||
pub fn allowed(&self) -> bool { return *self == UserFilterLevel::Allow; }
|
||||
}
|
||||
|
||||
pub struct Service {
|
||||
services: Services,
|
||||
db: Data,
|
||||
@@ -123,20 +139,32 @@ impl crate::Service for Service {
|
||||
}
|
||||
|
||||
impl Service {
|
||||
/// Returns true/false based on whether the recipient/receiving user has
|
||||
/// blocked the sender
|
||||
pub async fn user_is_ignored(&self, sender_user: &UserId, recipient_user: &UserId) -> bool {
|
||||
/// Returns a UserActionResult based on whether the recipient/receiving user
|
||||
/// has ignored or blocked the sender
|
||||
pub async fn user_filter_level(
|
||||
&self,
|
||||
sender_user: &UserId,
|
||||
recipient_user: &UserId,
|
||||
) -> UserFilterLevel {
|
||||
// can only return Allow or Ignore for now
|
||||
self.services
|
||||
.account_data
|
||||
.get_global(recipient_user, GlobalAccountDataEventType::IgnoredUserList)
|
||||
.await
|
||||
.is_ok_and(|ignored: IgnoredUserListEvent| {
|
||||
ignored
|
||||
.map(|ignored: IgnoredUserListEvent| {
|
||||
let sender_ignored_recipient = ignored
|
||||
.content
|
||||
.ignored_users
|
||||
.keys()
|
||||
.any(|blocked_user| blocked_user == sender_user)
|
||||
.any(|blocked_user| blocked_user == sender_user);
|
||||
|
||||
if sender_ignored_recipient {
|
||||
UserFilterLevel::Ignore
|
||||
} else {
|
||||
UserFilterLevel::Allow
|
||||
}
|
||||
})
|
||||
.unwrap_or(UserFilterLevel::Allow)
|
||||
}
|
||||
|
||||
/// Check if a user is an admin
|
||||
|
||||
Reference in new issue
Block a user