From 21bce9958269ba7e9b8a6a1d919c6c3b391ae66d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=97=8D+85CD?= <50108258+kwaa@users.noreply.github.com> Date: Thu, 26 Sep 2024 15:32:45 +0800 Subject: [PATCH] feat(apub): verify blocked --- .../src/activities/create_or_update/note.rs | 2 + .../src/activities/following/accept_follow.rs | 2 +- .../apub/src/activities/following/follow.rs | 4 +- .../src/activities/following/undo_follow.rs | 5 ++- .../like_or_announce/like_or_announce.rs | 4 +- .../like_or_announce/undo_like_or_announce.rs | 5 ++- crates/apub/src/lib.rs | 1 + crates/apub/src/utils/mod.rs | 3 ++ crates/apub/src/utils/verify_blocked.rs | 38 +++++++++++++++++++ 9 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 crates/apub/src/utils/mod.rs create mode 100644 crates/apub/src/utils/verify_blocked.rs diff --git a/crates/apub/src/activities/create_or_update/note.rs b/crates/apub/src/activities/create_or_update/note.rs index c4417bc7..4a5e5f1b 100644 --- a/crates/apub/src/activities/create_or_update/note.rs +++ b/crates/apub/src/activities/create_or_update/note.rs @@ -15,6 +15,7 @@ use crate::{ activities::CreateOrUpdateType, actors::ApubUser, objects::{ApubPost, Note}, + utils::verify_blocked, }; #[derive(Deserialize, Serialize, Debug)] @@ -97,6 +98,7 @@ impl ActivityHandler for CreateOrUpdateNote { async fn verify(&self, data: &Data) -> Result<(), Self::Error> { // TODO ApubPost::verify(&self.object, &self.id, data).await?; + verify_blocked(&self.id, data).await?; Ok(()) } diff --git a/crates/apub/src/activities/following/accept_follow.rs b/crates/apub/src/activities/following/accept_follow.rs index 8d2980c5..4ae7d623 100644 --- a/crates/apub/src/activities/following/accept_follow.rs +++ b/crates/apub/src/activities/following/accept_follow.rs @@ -78,7 +78,7 @@ impl ActivityHandler for AcceptFollow { } async fn verify(&self, _data: &Data) -> Result<(), Self::Error> { - // TODO + // TODO: just throw error Ok(()) } diff --git a/crates/apub/src/activities/following/follow.rs b/crates/apub/src/activities/following/follow.rs index 3b1b9513..c0d4d4cd 100644 --- a/crates/apub/src/activities/following/follow.rs +++ b/crates/apub/src/activities/following/follow.rs @@ -23,6 +23,7 @@ use url::Url; use crate::{ activities::{AcceptFollow, ApubReceivedFollow}, actors::ApubUser, + utils::verify_blocked, }; /// @@ -58,8 +59,9 @@ impl ActivityHandler for Follow { self.actor.inner() } - async fn verify(&self, _data: &Data) -> Result<(), Self::Error> { + async fn verify(&self, data: &Data) -> Result<(), Self::Error> { // TODO + verify_blocked(&self.id, data).await?; Ok(()) } diff --git a/crates/apub/src/activities/following/undo_follow.rs b/crates/apub/src/activities/following/undo_follow.rs index 075dc5f8..9166b269 100644 --- a/crates/apub/src/activities/following/undo_follow.rs +++ b/crates/apub/src/activities/following/undo_follow.rs @@ -11,7 +11,7 @@ use sea_orm::EntityTrait; use serde::{Deserialize, Serialize}; use url::Url; -use crate::{activities::Follow, actors::ApubUser}; +use crate::{activities::Follow, actors::ApubUser, utils::verify_blocked}; // https://github.com/LemmyNet/lemmy/blob/963d04b3526f8a5e9ff762960bfb5215e353bb27/crates/apub/src/protocol/activities/following/undo_follow.rs #[derive(Clone, Debug, Deserialize, Serialize)] @@ -44,8 +44,9 @@ impl ActivityHandler for UndoFollow { self.actor.inner() } - async fn verify(&self, _data: &Data) -> Result<(), Self::Error> { + async fn verify(&self, data: &Data) -> Result<(), Self::Error> { // TODO + verify_blocked(&self.id, data).await?; Ok(()) } diff --git a/crates/apub/src/activities/like_or_announce/like_or_announce.rs b/crates/apub/src/activities/like_or_announce/like_or_announce.rs index 4fcc3daa..a47822aa 100644 --- a/crates/apub/src/activities/like_or_announce/like_or_announce.rs +++ b/crates/apub/src/activities/like_or_announce/like_or_announce.rs @@ -22,6 +22,7 @@ use crate::{ activities::{ApubReceivedAnnounce, ApubReceivedLike, LikeOrAnnounceType}, actors::ApubUser, objects::ApubPost, + utils::verify_blocked, }; #[derive(Clone, Debug, Deserialize, Serialize)] @@ -48,8 +49,9 @@ impl ActivityHandler for LikeOrAnnounce { self.actor.inner() } - async fn verify(&self, _data: &Data) -> Result<(), Self::Error> { + async fn verify(&self, data: &Data) -> Result<(), Self::Error> { // TODO + verify_blocked(&self.id, data).await?; Ok(()) } diff --git a/crates/apub/src/activities/like_or_announce/undo_like_or_announce.rs b/crates/apub/src/activities/like_or_announce/undo_like_or_announce.rs index 7a4371a3..b69a382b 100644 --- a/crates/apub/src/activities/like_or_announce/undo_like_or_announce.rs +++ b/crates/apub/src/activities/like_or_announce/undo_like_or_announce.rs @@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize}; use url::Url; use super::LikeOrAnnounceType; -use crate::{activities::LikeOrAnnounce, actors::ApubUser}; +use crate::{activities::LikeOrAnnounce, actors::ApubUser, utils::verify_blocked}; #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] @@ -37,8 +37,9 @@ impl ActivityHandler for UndoLikeOrAnnounce { self.actor.inner() } - async fn verify(&self, _data: &Data) -> Result<(), Self::Error> { + async fn verify(&self, data: &Data) -> Result<(), Self::Error> { // TODO + verify_blocked(&self.id, data).await?; Ok(()) } diff --git a/crates/apub/src/lib.rs b/crates/apub/src/lib.rs index 96ee4800..c2e77ea4 100644 --- a/crates/apub/src/lib.rs +++ b/crates/apub/src/lib.rs @@ -3,6 +3,7 @@ pub mod actors; pub mod collections; pub mod links; pub mod objects; +mod utils; // #[cfg(test)] pub mod tests { diff --git a/crates/apub/src/utils/mod.rs b/crates/apub/src/utils/mod.rs new file mode 100644 index 00000000..babd8222 --- /dev/null +++ b/crates/apub/src/utils/mod.rs @@ -0,0 +1,3 @@ +mod verify_blocked; + +pub use verify_blocked::verify_blocked; diff --git a/crates/apub/src/utils/verify_blocked.rs b/crates/apub/src/utils/verify_blocked.rs new file mode 100644 index 00000000..6f8072e8 --- /dev/null +++ b/crates/apub/src/utils/verify_blocked.rs @@ -0,0 +1,38 @@ +use activitypub_federation::config::Data; +use axum::http::StatusCode; +use hatsu_db_schema::prelude::BlockedUrl; +use hatsu_utils::{AppData, AppError}; +use sea_orm::EntityTrait; +use url::Url; + +pub async fn verify_blocked(url: &Url, data: &Data) -> Result<(), AppError> { + let blocked_url = BlockedUrl::find().all(&data.conn).await?; + + if blocked_url + .clone() + .into_iter() + .filter(|url| url.is_instance) + .filter_map(|url| Url::parse(&url.id).ok()) + .map(|url| url.origin()) + .any(|instance| url.origin().eq(&instance)) + { + Err(AppError::new( + format!("blocked instance: {:?}", url.host_str()), + None, + Some(StatusCode::BAD_REQUEST), + )) + } else if blocked_url + .into_iter() + .filter(|url| !url.is_instance) + .filter_map(|url| Url::parse(&url.id).ok()) + .any(|actor| url.eq(&actor)) + { + Err(AppError::new( + format!("blocked actor: {}", url), + None, + Some(StatusCode::BAD_REQUEST), + )) + } else { + Ok(()) + } +}